队列是一种特殊的线性表,先进先出(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. poj2769 暴力

    //Accepted 208 KB 157 ms //纯暴力 //vis数组初始化时要用多少设置多少,不然TLE #include <cstdio> #include <cstrin ...

  2. 在android的spinner中,实现取VALUE值和TEXT值。 ZT

    在android的spinner中,实现取VALUE值和TEXT值.   为了实现在android的 spinner实现取VALUE值和TEXT值,我尝试过好些办法,在网上查的资料,都是说修改适配器, ...

  3. ubuntu下修改mysql默认字符编码出现的Job failed to start解决办法

    ubuntu下修改mysql默认字符编码出现的Job failed to start解决办法 前几天卸掉了用了好多年的Windows,安装了Ubuntu12.04,就开始各种搭环境.今天装好了MySQ ...

  4. susy-Toolkit 之翻译

    Toolkit工具包 The Susy 2.0 toolkit is built around our shorthand syntax. Use the shorthand to control e ...

  5. C#泛型(二)

    <1>.泛型方法 以前文章说到用一个泛型类 SortHelper 来做一个冒泡排序的处理,下面回顾一下之前的代码: public class SortHelper<T> whe ...

  6. HTTP Live Streaming直播(iOS直播)技术分析与实现

    前些日子,也是项目需要,花了一些时间研究了HTTP Live Streaming(HLS)技术,并实现了一个HLS编码器HLSLiveEncoder,当然,C++写的.其功能是采集摄像头与麦克风,实时 ...

  7. Android WindowManager悬浮窗:不需要申请权限实现悬浮

     Android WindowManager悬浮窗:不需要申请权限实现悬浮 附录文章1介绍了Android平台上的悬浮窗WindowManager,WindowManager悬浮窗可以悬浮在And ...

  8. 使用.bat 文件,批量编译项目文件。

    使用.bat 文件,批量编译项目文件. 2008-6-1来源:www.aspcool.com 作者:PCJIM 点击:次   path %path%;D:\Program Files\Microsof ...

  9. Howto add permanent static routes in Ubuntu

    Static routing is the term used to refer to the manual method used to set up routing. An administrat ...

  10. Linux Command Line 备忘

    1. 如果要删除目录, rmdir or rm -d 或许可以删除空目录,但是只有 rm -R 可以把目录以及其内容连带删除! 2. 查看文件大小: ls -l --block-size=G 还可以换 ...