普通佇列,迴圈佇列以及鏈佇列的相關操作
佇列,一種限定性的線性表。它只允許在表一端進行插入,而在表的另一端進行刪除操作。
普通佇列
基於此,我們定義了一個數據結構,包含首尾指標
class Queue{
Object[] data;
int front;
int rear;
}
置空佇列時 ,將rear=front=-1;
public static Queue initEmptyQueue(){
Queue queue=new Queue();
queue.data=new Object[MAX_SIZE];
queue.front=-1 ;
queue.rear=-1;
return queue;
}
在不考慮佇列為空的情況下,出佇列頭指標front++,在不考慮溢位的情況下,進佇列尾指標rear++
public static boolean inQueue(Queue queue,Object value){
queue.data[++queue.rear]=value;
return true;
}
public static Object outQueue(Queue queue){
return queue.data[++queue.front];
}
但是這樣會遇到問題,如下圖
當隊尾指標指向了陣列的最後一個位置,而隊頭指標不在0號位置時,他會出現假溢位的現象,即陣列中有空位置,但是預設已經滿了。為了解決這一問題,我們引入了迴圈佇列,即將隊尾和對頭連線起來
迴圈佇列
迴圈佇列的資料結構還是和普通佇列一樣,只不過在設定空佇列時將,rear和front設為了MAX_SIZE-1
class CycleQueue {
Object[] data;
int front;
int rear;
}
public static CycleQueue initEmptyQueue(){
CycleQueue cycleQueue=new CycleQueue();
cycleQueue.data=new Object[MAX_SIZE];
cycleQueue.front=MAX_SIZE-1;
cycleQueue.rear=MAX_SIZE-1;
return cycleQueue;
}
在進行判空的時候,只需要判斷front和rear是否相等
public static boolean isEmpty(CycleQueue cycleQueue){
if(cycleQueue.front==cycleQueue.rear)
return true;
return false;
}
接下來就是佇列中最重要的兩個函式,出佇列和入佇列。出佇列的思想:當佇列不為空的時候,將佇列的第一個元素出出佇列,用數學公式表達就是front=(front+1)%MAX_SIZE,然後返回該位置;進佇列的思想是,先判斷front指標和rear指標是否直接相鄰,若是直接相鄰,則表示佇列已滿,無法插入,若不相鄰,則直接插入,插入的位置為:rear=(rear+1)%MAX_SIZE.
public static boolean inQueue(CycleQueue cycleQueue,Object value){
if((cycleQueue.rear+1)%MAX_SIZE==cycleQueue.front)
return false;
cycleQueue.rear=(cycleQueue.rear+1)%MAX_SIZE;
cycleQueue.data[cycleQueue.rear]=value;
return true;
}
public static Object outQueue(CycleQueue cycleQueue){
if(isEmpty(cycleQueue)){
return null;
}
cycleQueue.front=(cycleQueue.front+1)%MAX_SIZE;
return cycleQueue.data[cycleQueue.front];
}
鏈佇列
為甚麼要使用練佇列呢?其實和鏈棧的思想是一致的,因為順序佇列總是需要分配固定的記憶體空間,若分配過大,容易造成空間浪費,若是分配過小,容易造成溢位,所以我們才使用了鏈佇列,在使用的過程中動態的分配空間。首先先看一下鏈佇列的資料結構
//將頭尾指標封裝在一起
class LinkQueue{
Node rear;
Node front;
}
//鏈佇列節點的型別
class Node{
Node next;
Object value;
}
首先建立一個帶頭結點的空佇列
public static LinkQueue initEmptyLinkQueue(){
LinkQueue linkQueue=new LinkQueue();
Node head=new Node();
head.next=null;
linkQueue.rear=linkQueue.front=head;
return linkQueue;
}
判斷佇列是否為空的思想和迴圈佇列相同,即判斷頭尾指標是否相等
public static boolean isEmpty(LinkQueue linkQueue){
if(linkQueue.rear==linkQueue.front)
return true;
return false;
}
最後看進佇列和出佇列兩個函式。進佇列的思想是:利用單鏈表尾插法的思想插入到連結串列的尾部,具體可參考單鏈表的建立;出佇列的思想是:如果佇列不為空,則將對列的頭指標指向第一個節點的下一個節點,然後返回第一個節點的值。
public static boolean inQueue(LinkQueue linkQueue,Object value){
Node node=new Node();
node.value=value;
node.next=linkQueue.rear.next;
linkQueue.rear.next=node;
linkQueue.rear=node;
return true;
}
public static Object outQueue(LinkQueue linkQueue){
if(isEmpty(linkQueue)){
return null;
}
Node node=linkQueue.front.next;
linkQueue.front.next=node.next;
if(linkQueue.front.next==null)
linkQueue.rear=linkQueue.front;
return node.value;
}
至此。佇列的基本操作就完成了。