1. 程式人生 > >佇列的定義以及實現

佇列的定義以及實現

佇列是隻允許在一端進行插入操作,而在另外一端進行刪除操作的線性表。

佇列是一種先進先出的線性表,簡稱FIFO,允許插入的一端稱之為隊尾,允許刪除的一端稱之為隊頭。

線性表有順序儲存和鏈式儲存,棧是線性表,佇列作為一種特殊的線性表,也同樣存在順序儲存結構和鏈式儲存結構。

入隊:在佇列的末尾追加一個元素,不需要移動任何元素,其時間複雜度為O(1);

出隊:佇列元素的出列是在隊頭,即下標為0的位置,即佇列中的所有元素都得向前移動,以保證佇列的隊頭,也就是下標為0的位置不為空,其時間複雜度為O(n);

一般,操作佇列,引入兩個指標來表示,front指標指向隊頭元素,rear指標指向隊尾元素的下一個位置,這樣當front等於rear時,此佇列不是還剩一個元素,而是空佇列。

迴圈佇列的定義:
順序佇列有一個缺點就是會造成假溢位,通過迴圈佇列可以解決假溢位,使得順序佇列的rear指標指向下標為0的位置,通常把這種頭尾相接的順序儲存結構稱為迴圈佇列。

判斷隊滿的條件:

(rear+1)%QueueSize==front

通用的計算佇列長度的公式為:

(rear-front+QueueSize)%QueueSize

迴圈佇列的順序儲存結構的程式碼如下:

#define MAXSIZE 10
typedef int QElemType;
typedef  struct
{
    QElemType data[MAXSIZE];
    int front;
    int
rear; } SqQueue;

迴圈佇列的初始化程式碼如下:

bool InitQueue(SqQueue *Q)
{
    Q->front = 0;
    Q->rear = 0;
    return true;
}

迴圈佇列的入隊操作程式碼如下:

//入隊操作
bool EnQueue(SqQueue *Q, QElemType e)
{
    if ((Q->rear + 1) % MAXSIZE == Q->front)
    {
        cout << "隊滿" << endl;
        return
false; } //將隊尾指標指向新插入元素 Q->data[Q->rear] = e; //將隊尾rear指標向後移動一個位置 Q->rear = (Q->rear + 1) % MAXSIZE; //列印新增到佇列中的元素 cout << e << endl; return true; }

迴圈佇列的出隊操作程式碼如下:

//出隊操作
bool DeQueue(SqQueue *Q, QElemType *e)
{
    //佇列為空
    if (Q->front == Q->rear)
    {
        cout << "隊空" << endl;
        return false;
    }
    *e = Q->data[Q->front];
    Q->front = (Q->front + 1) % MAXSIZE;
    //列印從佇列中出隊的元素
    cout << *e << endl;
    return true;
}

求佇列的長度:

//求佇列的長度
int GetQueueLength(SqQueue Q)
{
    return (Q.rear - Q.front + MAXSIZE) % MAXSIZE;
}

主函式中測試程式碼如下:

int main()
{
    SqQueue *S = new SqQueue;
    SqQueue *Q = InitQueue(S);
    //入隊10個元素
    cout << "向佇列中新增元素" << endl;
    for (auto i = 0; i < 10; i++)
    {
        EnQueue(Q, i);
    }
    //cout << "當前佇列的長度為:" << GetQueueLength(*Q) << endl;
    //出隊對中的元素,6個元素
    cout << "將佇列元素中的元素出隊" << endl;
    int temp = 0;
    for (auto i = 0; i < 15; i++)
    {
        DeQueue(Q, &temp);
    }
    delete S;
    return 0;
}

測試輸出如下所示:

碼碼小蟲

歡迎關注公眾號,分享一些Unity3D、C#、C++資料結構和演算法相關的學習知識。

碼碼小蟲