一、概述
队列(queue):一种只允许在一端进行插入,在另一端进行删除的线性表结构。运行插入的一端叫队尾(rear),允许删除的一端叫队头(font)。与LIFO 的栈不同,队列是一种FIFO表。
二、顺序存储结构的队列基本操作以及算法实现
基本操作:入队、出对、队列里的元素数量、置空队列、判断是否为空、读取队列头部首元素等。
根据基本操作抽象出基本类型:
public interface IQueue{
public void enQueue(Object obj);
public Object DeQueue();
public int size();
public void clear();
public boolean isEmpty();
public Object head();
}
顺序队列的数据结构:
约定:队尾指针指示队尾元素在一维数组中的当前位置,队头指针指示队头元素在一维数组中当前元素的前一个位置。
public class Queue implements IQueue{
public final int MAXSIZE = 100;
public int elem[] = new int[MAXSIZE];
public int front,rear;
public Queue(){
front = -1;//初始化队列
rear = -1;//初始化队列
}
}
2.1.入队操作
public void enQueue(int data){
if(rear>0 && rear==this.front)
Sysotem.out.println("Queue is overflow");
else
rear ++;
elem[rear] = data;
}
2.2.出队操作
public int deQueue(){
if(front>0 && rear==this.front)
Sysotem.out.println("Queue is empty");
rerurn -1;
else
front ++;
return elem[front] ;
}
三、循环队列基本操作以及算法实现
注意:假溢出现象
当尾部插入速度小于头部删除速度时,出现rear==front的现象,但是此时队列并没有满,而且正好相反的是队列此时为空,存储空间最大,但继续插入元素时,rear值已经到达MAXSIZE边界条件,此时无法插入也无法删除。
为了避免假溢出现象,我们可以将队列组织成一个类似单循环链表的结构,也就是尾部和头部相连,若依照之前的约定,队列头部指示的位置不存储元素,则此时判断队列为空和判断队列为满的条件分别为:
空:rear == front
满:(rear+1)%MAXSIZE == front;
3.1.循环队列的初始化
public Queue(){
rear =0;
front = 0;
}
3.2.判断是否为空
public boolean isEmpty(){
if(rear==front)
return true;
return false;
}
3.3.求队列长度操作
public int size(){
//取模运算需要考虑rear-front<0的情况
return ((MAXSIZE+rear-front)%MAXSIZE);
}
3.4.读取队头元素
public int head(){
if(front==rear)
rerurn 0;
else
return(elem[(front+1)%MAXSIZE]);
3.5.入队操作
public void enQueue(int data){
if((rear+1)%MAXSIZE==front)
System.out.println("Queue id overflow");
else{
rear = (rear+1) % MAXSIZE;
elem[rear] = data;
}
}
3.6.出队操作
public int deQueue(){
if(front==rear)
return 0;
else{
front = (front+1)%MAXSIZE;
return elem[front];
}
}
四、链式存储的队列基本操作以及算法实现
与栈的缺点类似,顺序表存储的队列空间固定,容易造成浪费或溢出,所以可以选用链表来存储队列。
队列的链式存储结构实现:
public class Node{
int data;
Node next;
}
public class LinkQueue implements IQueue{
public Node rear;
public Node front;
public LinkQueue(){
front = new Node();
front.next = null;
rear = front;
}
//实现基本操作的接口方法
}
4.1.判断=链式队列是否为空操作
public boolean isEmpty(){
if(front == rear)
return true;
return false;
}
4.2.求链式队列长度
public int size(){
int size = 0;
Node p = front.next;;
while(p!=null){
size++;
p = p.next;
}
return size;
}
4.3.读取链式队列头部元素
public int head(){
if(front==rear)
return 0;
else
return front.next.data;
}
4.4.链式队列入队操作
//尾插法建立链表
public void enQueue(int data){
Node s = new Node;
s.data = data;
s.next = null;
rear.next = s;
rear = s;
}
4.5.链式队列的出队操作
public int deQueue(){
int data;
Node p;
if(front==rear)
return 0;
else{
p = front.next;
front.next = p.next;//改变头指针
if(p.next == null)//如果队列中只有一个元素
rear == front;//则置空
data = p.data;
p=null;
return data;
}
}
热门评论
学习了。正好跟着敲一边,加深记忆。