1. 程式人生 > >普通佇列,迴圈佇列以及鏈佇列的相關操作

普通佇列,迴圈佇列以及鏈佇列的相關操作

佇列,一種限定性的線性表。它只允許在表一端進行插入,而在表的另一端進行刪除操作。

普通佇列

這裡寫圖片描述
基於此,我們定義了一個數據結構,包含首尾指標

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;
    }

至此。佇列的基本操作就完成了。