java_queue
队列是一种特殊的线性表,先进先出(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的更多相关文章
- Java_Queue接口
Queue接口 1.英文 a) Queue 队列 b) Deque ,Double ender queue缩写,双向队列 2.Queue接口 除了基本的 Collect ...
随机推荐
- hdu 2099
PS:因为还是不爽...继续水题...感觉这道题就是考输出.. 代码: #include "stdio.h" void cal(int a,int b); int main(){ ...
- 修改主机名Ubuntu
主机名存放在/etc/hostname 修改保存即可
- Mac快捷键 Xcode快捷键
Mac OSX 快捷键&命令行 一.Mac OSX 快捷键 ctrl+shift 快速放大dock的图标会暂时放大,而 ...
- IOS 作业项目(4)步步完成 画图 程序(上)
先上流程图
- HDU5441 Travel 并查集
http://acm.hdu.edu.cn/showproblem.php?pid=5441 无向图,n个点,m条带权边,q次询问,给出数值d,点a可以到点b当且仅当存在一条路线其中最大的权值不超过d ...
- java作业3
Java字段初始化的规律: 静态初始化生成实例之后(就是new之后)变成你赋给它的值 ,先执行静态初始化,如果没有实例化,按照初始化块和构造方法在程序中出现的顺序执行. 当多个类之间有继承关系时,创建 ...
- [转]Golang Gob编码
Golang Gob编码 2012-08-24 09:47 by 轩脉刃, 5119 阅读, 1 评论, 收藏, 编辑 gob是Golang包自带的一个数据结构序列化的编码/解码工具.编码使用Enco ...
- windows服务部署与卸载
同事问到windows service的东东,现在整理一下,用c#如何创建一个windows service,以及如何调试.部署.卸载. 一.创建windows service 1. 打开VS2008 ...
- soapdenovo
配置文件中的=号两边不能有空格,否则会报错 SOAPdenovo-63mer_v2.0 all -s TongJiN2.config -p 25 -K 63 -d 1 -R -F -o Lily_2 ...
- 【字体区别】Serif和Sans Serif
[字体区别]Serif和Sans Serif 在西方国家罗马字母阵营中,字体分为两大种类:Sans Serif和Serif,打字机体虽然也属于Sans Serif,但由于是等宽字体,所以另外独立出Mo ...