1. 程式人生 > >佇列的鏈式儲存及實現

佇列的鏈式儲存及實現

在佇列的順序儲存中,我們看到了迴圈佇列面臨著陣列可能溢位的問題。而對於佇列的鏈式儲存來說,則不存在佇列長度的問題。佇列的鏈式儲存結構是線上性錶鏈式儲存基礎上,添加了兩個指標:頭指標(front)和尾指標(rear)。front指向連結串列的頭結點,而rear指向連結串列的最後一個節點。當front與rear指標重合時即front = rear時,我們就認為佇列為空。由於佇列元素的新增是在執行時分配記憶體,除非系統中沒有足夠的記憶體來分配,否則就不存在佇列為滿的情況。

佇列的鏈式儲存涉及的主要操作有:初始化、判斷佇列是否為空、入佇列操作、出佇列操作、返回佇列的長度等操作。其對應的實現程式碼如下所示:

#define MAXSIZE 20
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0

typedef int Status;
//佇列的鏈式儲存結構
typedef struct QNode{
    ElemType data;//連結串列節點的資料元素
    struct QNode *next;//指向下一個連結串列節點指標
}QNode,*QNodePtr;

typedef struct LinkQueue{
    QNodePtr front,rear;//佇列的頭指標和尾指標
    int count;//佇列元素的個數
}LinkQueue;


/* *
 * 初始化佇列鏈式儲存結構
 * 讓佇列為空
 * */
void InitQueue(LinkQueue *Q){
    QNodePtr H = (QNodePtr)malloc(sizeof(QNode));
    H->next = NULL;
    Q->front = Q->rear = H;//佇列的頭指標和尾指標相同,佇列為空
    Q->count = 0;//記錄佇列的實際長度
}

/* *
 * 元素入佇列
 * 成功返回1
 * 失敗返回0
 * */
Status EnQueue(LinkQueue *Q,ElemType e){
    QNodePtr m = (QNodePtr)malloc(sizeof(QNode));//建立一個新的連結串列節點
    if(!m)
        return ERROR;//記憶體分配失敗

    m->data = e;
    m->next = NULL;
    Q->rear->next = m;//佇列的尾指標指向新插入的節點
    Q->rear = m;
    Q->count++;//佇列元素加1
    return OK;
}

/* *佇列元素出佇列
 * 成功返回1,並把元素通過e返回
 * 失敗返回0
 */
Status DeQueue(LinkQueue *Q,ElemType *e){
    if(Q->front == Q->rear)
        return ERROR;//佇列為空
    QNodePtr p;
    p = Q->front->next;//佇列的首個節點
    *e = p->data;
    Q->front->next = p->next;//刪除佇列首節點
    if(Q->rear == p)
        Q->rear = Q->front;//佇列只有一個元素,刪除後為空連結串列,需要更新尾節點列表
    free(p);
    Q->count--;
    return OK;
}

/* *
 * 判斷佇列是否為空
 * 如果為空則返回TRUE,否則返回FALSE
 * */

Status QueueEmpty(LinkQueue Q){
    if(Q.front == Q.rear)
        return TRUE;
    else
        return FALSE;
}
測試的程式碼如下:
int main(){
    LinkQueue Q;
    InitQueue(&Q);
    if(QueueEmpty(Q))
        printf("The queue is empty\n");

    int i;
    for(i = 0; i < 10; i++){
        int e = rand()%50 + 1;
        if(EnQueue(&Q,e))
            printf("Insert a number:%d to the queue\n",e);
        printf("The Queue length is %d\n",Q.count);
    }


    int m;
    while(!QueueEmpty(Q)){
        if(DeQueue(&Q,&m))
            printf("delete the element success:%d and the queue length is:%d\n",m,Q.count);
    }
    return 0;
}