队列是一种特殊的线性表,先进先出(first in first out)FIFO,它只允许在表的前端(front)进行删除操作,只允许在表的后端(rear)进行插入操作。

实际应用:排队等待公交车,银行或者超市里的等待列队

出现假溢出的时候的一般解决方法:

一是将队列元素向前平移,对应的队列的顺序存储结构及实现中的a实现

二循环队列,对应的循环队列实现

1.队列的顺序存储结构及实现

a.没有控制队列容量大小的普通队列,数组移位实现(无假溢出现象)

package collectionsFramework.queue;

/**
* @Package collectionsFramework.queue * @ClassName: SequenceQueue * @Description: TODO(这里用一句话描述这个类的作用) * @author andy * @date 2013-11-21 下午05:26:10 */
public class SequenceQueue<T> {
//队列个数
private int size;
//装载元素的数组
private Object[] elementData;
//默认容量大小
private int defaultCapacity = 16;
//容量大小
private int capacity;
//增量大小
private int incrementCapacity; public SequenceQueue(){
elementData = new Object[defaultCapacity];
} public SequenceQueue(int capacity){
this.capacity = capacity;
elementData = new Object[capacity]; } public SequenceQueue(int capacity,int incrementCapacity){
this(capacity);
this.incrementCapacity = incrementCapacity;
} //入列
public synchronized T add(T element){
if(null == element){
return null;
}
boolean flag = true;
try {
ensureCapacity();
} catch (Exception e) {
try {
ensureCapacity();
} catch (Exception e1) {
flag = false;
try {
throw new Exception("第二次数组扩容失败!");
} catch (Exception e2) {
e2.printStackTrace();
}
}
}
if(flag){
elementData[size++] = element;
return element;
} return null;
} //出列
public synchronized T poll(){
if(size == 0){
return null;
}
Object[] oldData = elementData;
elementData = new Object[elementData.length];
try {
System.arraycopy(oldData, 1, elementData, 0, elementData.length - 1);
} catch (Exception e) {
try {
throw new Exception("移除元素,数组元素往前移植时出错");
} catch (Exception e1) {
e1.printStackTrace();
}
e.printStackTrace(); }
size--;
return (T)oldData[0]; } //移除头部元素,但不删除
public synchronized T peek(){
if(0 == size){
return null;
}
return (T)elementData[0];
} //确保容量够
private synchronized void ensureCapacity() {
if(size == elementData.length){
int length = 0;
if(incrementCapacity > 0){
length = elementData.length + length;
}else{
length = elementData.length<<1;
}
Object[] oldData = elementData;
elementData = new Object[length];
try {
System.arraycopy(oldData, 0, elementData, 0, size-1);
} catch (Exception e) {
try {
throw new Exception("第一次数组扩容失败!");
} catch (Exception e1) {
e1.printStackTrace();
}
}
}
} public String toString() {
if (0==size) {
return "[]";
} else {
StringBuilder sb = new StringBuilder("[");
for (int i = 0; i < size; i++) {
sb.append(elementData[i].toString() + ", ");
}
int len = sb.length();
return sb.delete(len - 2, len).append("]").toString();
}
} public static void main(String[] args) {
SequenceQueue<String> queue = new SequenceQueue<String>(10);
for(int i = 0; i<100; i++){
System.out.println("元素:" + queue.add("a" + i) + " 入列");
System.out.println("字符串:" + queue);
if(queue.size == queue.capacity){
System.out.println("已经有"+queue.capacity+"个未运行的任务数");
System.out.println("元素:" + queue.poll() + "---------出列");
}
}
while(queue.size != 0){
System.out.println("字符串:" + queue);
System.out.println("元素:" + queue.poll() + " 出列");
}
}
}

b.控制了容量大小的队列(会有假溢出现象)

package collectionsFramework.queue;

import java.util.Arrays;

/**
* @Package collectionsFramework.queue
*
* @ClassName: SequenceQueue2
*
* @Description: TODO(这里用一句话描述这个类的作用)
*
* @author andy
*
* @date 2013-11-24 下午06:52:39
*/
public class SequenceQueue3<T> {
private int DEFAULT_SIZE = 10;
// 保存数组的长度。
private int capacity;
// 定义一个数组用于保存顺序队列的元素
private Object[] elementData;
// 保存顺序队列中元素的当前个数
private int front = 0;
private int rear = 0; // 以默认数组长度创建空顺序队列
public SequenceQueue3() {
capacity = DEFAULT_SIZE;
elementData = new Object[capacity];
} // 以一个初始化元素来创建顺序队列
public SequenceQueue3(T element) {
this();
elementData[0] = element;
rear++;
} /**
* 以指定长度的数组来创建顺序队列
*
* @param element
* 指定顺序队列中第一个元素
* @param initSize
* 指定顺序队列底层数组的长度
*/
public SequenceQueue3(T element, int initSize) {
this.capacity = initSize;
elementData = new Object[capacity];
elementData[0] = element;
rear++;
} // 获取顺序队列的大小
public int length() {
return rear - front;
} // 插入队列
public T add(T element) {
if (rear > capacity - 1) {
throw new IndexOutOfBoundsException("队列已满的异常");
}
elementData[rear++] = element;
return element;
} // 移除队列
public T remove() {
if (empty()) {
throw new IndexOutOfBoundsException("空队列异常");
}
// 保留队列的rear端的元素的值
T oldValue = (T) elementData[front];
// 释放队列的rear端的元素
elementData[front++] = null;
return oldValue;
} // 返回队列顶元素,但不删除队列顶元素
public T element() {
if (empty()) {
throw new IndexOutOfBoundsException("空队列异常");
}
return (T) elementData[front];
} // 判断顺序队列是否为空队列
public boolean empty() {
return rear == front;
} // 清空顺序队列
public void clear() {
// 将底层数组所有元素赋为null
Arrays.fill(elementData, null);
front = 0;
rear = 0;
} public String toString() {
if (empty()) {
return "[]";
} else {
StringBuilder sb = new StringBuilder("[");
for (int i = front; i < rear; i++) {
sb.append(elementData[i].toString() + ", ");
}
int len = sb.length();
return sb.delete(len - 2, len).append("]").toString();
}
} public static void main(String[] args) {
SequenceQueue3<String> queue = new SequenceQueue3<String>();
for (int i = 0; i < queue.capacity; i++) {
System.out.println("元素:" + queue.add("a" + i) + "入列");
} /*int j = 0;
while (!queue.empty()) {
j++;
System.out.println("元素:" + queue.remove()
+ "+++++++++++++++++=====出列");
if (!queue.empty()) {
System.out.println("元素:" + queue.add("j" + j) + "入列");
}
if (100 == j) {
break;
}
}*/ while (!queue.empty()) {
System.out.println("元素:" + queue.remove() + "出列");
}
}
}

2.队列的链式存储结构及实现

package collectionsFramework.queue;

/**
* @Package collectionsFramework.queue
*
* @ClassName: LinkQueue
*
* @Description: TODO(这里用一句话描述这个类的作用)
*
* @author andy
*
* @date 2013-11-24 下午10:30:26
*/
public class LinkQueue<T> {
// 定义一个内部类Node,Node实例代表链队列的节点。
private class Node {
// 保存节点的数据
private T data;
// 指向下个节点的引用
private Node next; // 无参数的构造器
public Node() {
} // 初始化全部属性的构造器
public Node(T data, Node next) {
this.data = data;
this.next = next;
}
} // 保存该链队列的头节点
private Node front;
// 保存该链队列的尾节点
private Node rear;
// 保存该链队列中已包含的节点数
private int size; // 创建空链队列
public LinkQueue() {
// 空链队列,front和rear都是null
front = null;
rear = null;
} // 返回链队列的长度
public int length() {
return size;
} // 将新元素加入队列
public T add(T element) {
if (size == 0) {
front = new Node(element, null);
rear = front;
} else {
//rear = new Node(element, null);//这些写虽然有下一个结点,但是当前结点对下个结点的引用都是空的
//创建新节点
Node newNode = new Node(element , null);
//让尾节点的next指向新增的节点
rear.next = newNode;
//以新节点作为新的尾节点
rear = newNode;
}
size++;
return element; } // 访问链式队列中最后一个元素
public T element() {
return rear.data;
} // 判断链式队列是否为空队列
public boolean empty() {
return size == 0;
} // 删除队列front端的元素
public T remove() {
if (0 != size) {
// 保存之前的前端结点
Node oldFront = front;
// 前端结点移除就没有了,所以将前端的下个节点设置为新的前端结点,并把将要移除的前端结点的对下个结点的引用设为null
Node newfront = front.next;
front.next = null;
front = newfront;
size--;
return oldFront.data;
} else {
return null;
}
} // 清空链队列
public void clear() {
// 将front、rear两个节点赋为null
front = null;
rear = null;
size = 0;
} public String toString() {
// 链队列为空链队列时
if (empty()) {
return "[]";
} else {
StringBuilder sb = new StringBuilder("[");
for (Node current = front; current != null; current = current.next) {
sb.append(current.data.toString() + ", ");
}
int len = sb.length();
return sb.delete(len - 2, len).append("]").toString();
}
} public static void main(String[] args) {
LinkQueue<String> queue = new LinkQueue<String>();
for(int i = 0; i<100; i++){
System.out.println("元素:" + queue.add("a" + i) + " 入列");
System.out.println("字符串表示:" + queue);
if(queue.size == 20){
System.out.println("已经有"+"20"+"个未运行的任务数");
System.out.println("元素:" + queue.remove() + "---------出列");
}
}
//queue.clear();
while(queue.size != 0){System.out.println("字符串表示:" + queue);
System.out.println("元素:" + queue.remove() + " 出列");
}
}
}

3.循环队列(顺序结构存储实现)

package collectionsFramework.queue;

/**
* @Package collectionsFramework.queue
*
* @ClassName: LoopQueue
*
* @Description: TODO(这里用一句话描述这个类的作用)
*
* @author andy
*
* @date 2013-11-24 下午11:32:52
*/
public class LoopQueue<T> {
private int DEFAULT_SIZE = 10;
// 保存数组的长度。
private int capacity;
// 定义一个数组用于保存循环队列的元素
private Object[] elementData; private int front = -1;
private int rear = -1; // 以默认数组长度创建空循环队列
public LoopQueue() {
capacity = DEFAULT_SIZE;
elementData = new Object[capacity];
} // 判断是否为空
private boolean empty() {
return front == -1;
} // 判断栈是否满了
public boolean isFull() {
return (rear + 1) % capacity == front;
} // 置空
public void clear() {
front = rear = -1;
} //元素个数
/*public int length() {
if (empty()) {
return 0;
}
return (rear - front + capacity) % capacity;
}*/ public int length() {// 队列长度
if(empty()){
return 0;
} if (rear >= front)
return rear - front + 1;
else
return capacity - (front - rear) + 1;
} // 插入队列
public T add(T element) {
if (isFull()) {
System.out.println("队列已经满了");
return null;
} if (empty()) {
front = rear = 0;
} else {
rear = (rear + 1) % capacity;
}
elementData[rear] = element;
return element;
} // 移除队列顶部元素
public T remove() {
if (empty()) {
System.out.println("空队列");
throw new IndexOutOfBoundsException("空队列异常");
}
T oldData = (T) elementData[front];
elementData[front] = null;
if (front == rear) {
clear();
return oldData;
}
front = (front + 1) % capacity;
return oldData;
} // 返回队列顶部元素,但不删除元素
public T element() {
if (empty()) {
return null;
}
return (T) elementData[front + 1];
} public String toString() {// 打印所有元素
if (empty()) {
return "[]";
}else{
StringBuilder sb = new StringBuilder("[");
int i = front;
int j = 0;
while(j < length()){
sb.append(elementData[i].toString() + ", ");
i = (i + 1) % capacity;
j++;
}
/*for (int j = 0; j < length(); i = (i + 1) % capacity, j++){
sb.append(elementData[i].toString() + ", ");
}*/
int len = sb.length();
return sb.delete(len - 2, len).append("]").toString();
}
} public static void main(String[] args) {
LoopQueue<String> queue = new LoopQueue<String>();
for (int i = 0; i < 100; i++) {
System.out.println("元素:" + queue.add("a" + i) + " 入列");
System.out.println("字符串表示:" + queue);
if(queue.length() == queue.capacity){
System.out.println("元素:"+queue.remove() + " +++++++++++++出列");
}
//System.out.println("元素长度:" + queue.length()); }
//queue.clear();
while(queue.length() != 0){
System.out.println("字符串表示:" + queue);
System.out.println("元素:"+queue.remove() + " 出列"); }
} }

java_queue的更多相关文章

  1. Java_Queue接口

    Queue接口 1.英文 a)         Queue 队列 b)         Deque ,Double ender queue缩写,双向队列 2.Queue接口 除了基本的 Collect ...

随机推荐

  1. poj2250 最长上升子序列 + 输出

    //Accepted 208 KB 0 ms //最长公共上升子序列+输出 //dp //输出时用的递归输出,注意条件判断 #include <cstdio> #include <c ...

  2. oracle视图如何使用

    1.视图的概述 视图其实就是一条查询sql语句,用于显示一个或多个表或其他视图中的相关数据.视图将一个查询的结果作为一个表来使用,因此视图可以被看作是存储的查询或一个虚拟表.视图来源于表,所有对视图数 ...

  3. Android Context

    http://www.cnblogs.com/android100/p/Android-Context.html

  4. ubuntu添加共享出错

    早上设置一个共享目录share. 右键共享,之后系统自动安装软件samba,之后共享出错: "net usershare"返回错误 255:net usershare: canno ...

  5. false等于0???

    看到一个函数strpos($string,$str),用于在字符串$string中查找$str,如果在$string中查找到$str,则返回第一次出现的位置,起始位置为0:如果$string中不包含$ ...

  6. Python OpenCV——Image

    最近看MATLAB有点看不下去...就忍不住回到python的怀抱.研究下OpenCV,就当放松啦,对视觉还是很感兴趣的. 这里和之后代码大部分是来自这里的文档. 首先是对图片的处理. ''' imp ...

  7. HTML中的鼠标光标属性

    在网页中默认的鼠标指针只有两种,一种是最普通的箭头,另一种是当移动到链接上时出现的“小手”.但现在越来越多的网页都使用了CSS鼠标指针技术,当将鼠标移动到链接上时,可以看到多种不同的效果.CSS可以通 ...

  8. HDOJ三部曲-DP-1017-pearls

    Pearls Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 20000/10000K (Java/Other) Total Submis ...

  9. 【LEETCODE OJ】Copy List with Random Pointer

    Problem link: http://oj.leetcode.com/problems/copy-list-with-random-pointer/ Deepcopy a linked list ...

  10. UI基础:DataPersistent.沙盒

    沙盒是系统为每一个应用程序生成的一个特定文件夹,文件夹的名字由一个十六进制数据组成,每一个应用程序的沙盒文件名都是不一样的,是由系统随机生成的. 沙盒主目录: NSString *homePath = ...