队列是一种特殊的线性表,先进先出(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. Block编程值得注意的那些事儿

    [深入浅出Cocoa]Block编程值得注意的那些事儿   [深入浅出Cocoa]Block编程值得注意的那些事儿 罗朝辉 (http://www.cnblogs.com/kesalin/) 本文遵循 ...

  2. form表单select联动

    下拉列表:二级联动菜单 Select对象的常用属性 options[]:返回所有option组成的一个数组: name:名称 value:option的value的值 length:设置或读取opti ...

  3. 在Linux下用fdisk创建分区

    一.输入 fdisk -l /dev/sda ,观察硬盘之实体使用情形.二.输入 fdisk /dev/sda,可进入分割硬盘模式. 1. 输入 m 显示所有命令列示. 2. 输入 p 显示硬盘分割情 ...

  4. iOS常用设计模式:MVC、单例、代理、观察者。

    MVC 模型-视图-控制器(MVC)设计模式 MVC根据角色划分类,涉及到三个角色: Model:模型保存应用程序的数据. View:视图是模型的可视化表示以及用户交互的控件. Controller: ...

  5. (Your)((Term)((Project)))

    Description You have typed the report of your term project in your personal computer. There are seve ...

  6. C++11 | 正则表达式(4)

    C++11还支持正则表达式里的子表达式(也叫分组),用sub_match这个类就行了. 举个简单的例子,比如有个字符串"/id:12345/ts:987697413/user:678254& ...

  7. GOLANG 反射法则

    译自[blog.golang.org/laws-of-reflection] 在计算机中, 反射是程序通过类型,检测到它自己的结构能力:是一种元编程程:也是一个具大的混淆点 在本文中,我们将通过解释反 ...

  8. DBImg: 图片文件-二进制文件的转换

    using System; using System.IO; using System.Drawing; //using System.Collections.Generic; //using Sys ...

  9. 实现Magento多文件上传代码功能开发

    在Magento中上传单个文件很简单,可以直接在继承的Mage_Adminhtml_Block_Widget_Form类中直接添加如下组件Field:  对于图片:   $fieldset->a ...

  10. 【转】MySQL命令

    1.连接Mysql 格式: mysql -h主机地址 -u用户名 -p用户密码 1.连接到本机上的MYSQL.首先打开DOS窗口,然后进入目录mysql\bin,再键入命令mysql -u root ...