1. 程式人生 > >佇列的鏈式儲存與順序儲存

佇列的鏈式儲存與順序儲存

佇列是一種先進先出的線性表,佇列也有兩種結構:順序儲存和鏈式儲存

一:佇列的鏈式儲存結構

為了實現鏈式儲存,就要設定結點資訊——元素和指向下一個結點的指標。為了實現佇列的先進先出(FIFO)的功能,就要有兩個指標指向開始和結尾,才能方便的進行插入和刪除。但是如何表示佇列為空呢?當然可以讓指向頭和指向尾的指標指向NULL,不過可以像連結串列那樣設定頭結點,就更容易表示了。圖示如下:


1:佇列的結點資訊表示:

typedef struct QNode{
    ElemType data;
    struct QNode *next;
}QNode,*QueuePtr;

typedef struct{
    QueuePtr front; //頭指標
    QueuePtr rear;  //尾指標
}linkqueue;

2:初始化結點資訊
//初始化頭尾指標結點資訊,以及頭結點資訊
Status queue_init(linkqueue *Q)
{
    Q->front = Q->rear = (QueuePtr)malloc(sizeof(QNode));
    if(!(Q->front))
        exit(-1);
    Q->front->next = NULL;  //初始化頭結點資訊
    return 1;
}
注意:初始化頭尾指標結點資訊,以及頭結點資訊

3:插入結點(注意看評註資訊)

//建立結點並插入到佇列中,注意要照顧到所有的指標資訊!
Status enqueue(linkqueue *Q,ElemType e)
{
    QueuePtr p = (QueuePtr)malloc(sizeof(QNode));
    if(!p)
        exit(-1);
    p->data = e;
    p->NULL;
    Q->rear->next = p;
    Q->rear = p;
    return 1;
}
4:刪除結點
Status dequeue(linkqueue *Q,ElemType *e)
{
    if(Q->front == Q->rear)
        return 0;
    QueuePtr p = Q->front->next;
    *e = p->data;
    Q->front->next = p->next;
    if(Q->front == Q->rear)     //必須考慮到刪除最後一個結點的時候,要調整尾指標的資訊!
        Q->rear = Q->front;
    free(p);
    return 1;
}
注意處理尾指標情況!

二:佇列的順序儲存結構

1:順序儲存有如下特點

(1)由於順序儲存,通常通過陣列來實現,這是就應該設定QUEUEININTSIZE和QUEUEINCREMENT。

(2)但是,我們為了有效利用空間,不能讓空間無限增大,就應該採用迴圈佇列的模式:元素在陣列為放不下時從陣列頭開始放置。因此只能設定一個初始化空間大小QUEUEININTSIZE,不再附設增量。

(3)這裡類似棧的順序儲存,front指標指向要出隊的元素,rear指向最後一個元素的下一個位置。

(4)貌似要設定兩個結構,一個是陣列資訊,一個是頭尾指標資訊。但這裡可以將兩個組合到一起,同時頭尾指標弱化為陣列的“索引座標”。

(5)當rear == front時,表示為空,當(rear+1)%QUEUEINITSIZE == front時,表示佇列已滿。一方面要注意對陣列長度去模,另一方面空出一個位置不放元素,以判定佇列滿的狀態。

(6)當rear和front增加1變動的時候,都要通過rear=(rear+1)%QUEUEINITSIZE方式來賦值。

2:順序儲存的示意圖


3:佇列的儲存結構表示

#define MAXQSIZE 100
typedef struct{
    ElemType *base;
    int front;
    int rear;
}SqQueue;

4:佇列初始化
Status queue_init(SqQueue *Q)
{
    Q->base = (ElemType *)malloc(MAXQSIZE * sizeof(ElemType));
    if(!Q->base)
        exit(-1);
    Q->front = Q->rear = 0;
    return 1;
}

5:插入元素
Status enqueue(SqQueue *Q,ElemType e)
{
    if((Q->rear + 1)%MAXQSIZE == Q->front)
        return 0;
    Q->base[Q->rear] = e;
    Q->rear = (Q->rear + 1)%MAXQSIZE;
    return 1;
}

6:刪除元素
Status dequeue(SqQueue *Q,ElemType *e)
{
    if(Q->front == Q->rear)
        return 0;
    *e = Q->base[Q->front];
    Q->front = (Q->front + 1)%MAXQSIZE;
    return 1;
}

7:返回元素個數
int queuelength(SqQueue Q)
{
    return (Q->rear - Q->front + MAXQSIZE)%MAXQSIZE;
}