队列也叫做先进先出表,分为顺序存储和链式存储。
顺序存储:
使用一个数组,2-3个整形变量实现。数组保存顺序存储队列中的元素,一个整型变量存储队首元素的位置,另一个整型变量存储队尾元素的位置,第三个变量存储队列的长度(可以不使用)。通常把指向队首元素前一个位置的变量叫做队首指针,由它加一可以得到队首元素下标的位置,把指向队尾元素的变量叫做队尾指针。
在顺序存储结构中,若省略长度域length,那么此时长度为queueArray.length的数组空间只能存储长度为queueArray.length-1的队列,即必须有一个位置是空闲单元。如果使用全部的数组空间,当队首指针和队尾指针指向同一个位置的时候,可能为空队列也可能为满队列,即存在二义性。
每次向队列插入一个元素时,需要首先使队尾指针后移一个位置,然后再向这个位置写入数据。当队尾指针指向数组空间的最后一个位置(即queueArray.length-1)时,若队首元素的前面仍然存在空闲的位置,则表明队列未占满整个空间,下一个存储位置应该是下标0的空闲位置,因此,首先使队尾指针指向下标为0的位置,然后再向该位置写入数据。因此顺序存储的队列也叫循环队列。
package org.queen.cn;
public interface QueenADT {
/**
* 元素进队,即向队列尾添加元素
* @param obj
*/
public void enter(Object obj);
/**
* 元素离队,即从队首删除元素
* @return
*/
public Object leave();
/**
* 返回队首元素的值
* @return
*/
public Object peek();
/**
* 判断队列是否为空
* @return
*/
public boolean isEmpty();
/**
* 清除队列中的所有元素使之变为空队列
*/
public void clear();
}
package org.queen.cn;
/**
* 队列的顺序存储和操作实现(循环队列)
* 在顺序存储定义中,第一个位置(0)一般写的数据的长度,若省略数据长度域length也是可行的,但此时的长度为queryArry.length
* 只能存储长度为queryArry.length的队列
* @author Administrator
*
*/
public class SequenceQueen implements QueenADT {
final int maxSize=10;
private Object queryArray[];
private int front;//队首指针--..通常是指向队首元素的前一个位置的变量,由它+1即可得到队首元素的下标
private int rear;//对尾指针--..通常是指向队尾元素的变量
public SequenceQueen() {
// TODO Auto-generated constructor stub
front=rear=0;
queryArray=new Object[maxSize];
}
public SequenceQueen(int n) {
// TODO Auto-generated constructor stub
if(n<=0){
System.out.println("数组长度大于0");
}
front=rear=0;
queryArray=new Object[n];
}
@Override
public void enter(Object obj) {
// TODO Auto-generated method stub
if((rear+1)%queryArray.length==front){
//队列已经满了 开辟新的存储空间
Object[] p=new Object[queryArray.length*2];
if(rear==queryArray.length-1){
for(int i=0;i<rear;i++){
p[i]=queryArray[i];
}
}else{
//先复制原队列前面内容,在复制其后面的内容
int i,j = 1;
for(i=front+1;i<queryArray.length;i++,j++){
p[j]=queryArray[i];
}
for(i=0;i<=rear;i++,j++){
p[j]=queryArray[i];
}
front=0;
rear=queryArray.length-1;
}
queryArray=p;
}
rear=(rear+1)%queryArray.length;
queryArray[rear]=obj;
}
@Override
public Object leave() {
// TODO Auto-generated method stub
if(front==rear){
System.out.println("队列是空的");
}
front=(front+1)%queryArray.length;//队首指针向后移动一位
return queryArray[front];
}
@Override
public Object peek() {
// TODO Auto-generated method stub
if(front==rear){
System.out.println("队列是空的");
}
return queryArray[(front+1)%queryArray.length];
}
@Override
public boolean isEmpty() {
// TODO Auto-generated method stub
return front==rear;
}
@Override
public void clear() {
// TODO Auto-generated method stub
front=rear=0;
}
}
package org.queen.cn;
/***
* 队列的链接存储结构和操作实现
* @author Administrator
*
*/
public class LinkQueen implements QueenADT {
private Node front;//队首指针,,指向队首节点的存储地址(引用)
private Node rear;//队尾指针,,指向队尾节点的存储地址(引用)
private class Node{
private Object data;//数据域
private Node next; //指针域 存储下一个节点的引用
public Node(Node next){
this.next=next;
}
public Node(Object obj,Node next){
this.data=obj;
this.next=next;
}
}
public LinkQueen() {
// TODO Auto-generated constructor stub
front=rear=null; //队列初始为空,即把队首队尾指针==null
}
@Override
public void enter(Object obj) {
// TODO Auto-generated method stub
if(rear==null){
front=rear=new Node(obj,null);
}else{
rear=rear.next=new Node(obj,null);
}
}
@Override
public Object leave() {
// TODO Auto-generated method stub
if(front==null){
//队列为空
System.out.println("队列为空");
return null;
}
Object x=front.data; //队首节点的值赋值x暂存
front=front.next; //删除队首节点
if(front==null){
rear=null;
}
return x;
}
@Override
public Object peek() {
// TODO Auto-generated method stub
if(front==null){
//队列为空
System.out.println("队列为空");
return null;
}
return front.data;
}
@Override
public boolean isEmpty() {
// TODO Auto-generated method stub
return front==null;
}
@Override
public void clear() {
// TODO Auto-generated method stub
front=rear=null;
}
}
学习数据结构,深深为前人智慧折服。