數據結構:鏈表隊列的實現


數據結構:鏈表隊列的實現

快速開始

  隊列是一種和棧相反的,遵循先進先出原則的線性表。此文章使用鏈表來實現隊列。

  

  如上圖所示,就像一個自來水管,先進入水管的水先從水龍頭出來,即Front位置的元素最先出隊列,因為它們是最先入隊列的。

   

2、實現隊列

  本代碼是嚴蔚敏教授的數據結構書上面的偽代碼的C語言實現代碼。

  一定要多思考,多問為什么!

  首先我們定義了一些常量:

#include <stdio.h>
#include <stdlib.h>

#define OK 1
#define ERROR 0

typedef int QElemtype;
typedef int status;

2.1、對隊列和節點的結構定義

  既然底層是鏈表,那么每個節點不僅要保存當前值,還要指向下一個節點的地址。

  對於隊列來說,每次插入值都是在隊尾(rear),每次取出值都是在隊首(head),所以,我們一定是有兩個變量來指向隊頭與隊尾的。

  

  綜上所述,我們結構定義代碼如下:

typedef struct QNode //對節點的結構定義
{
    QElemtype data;
    struct QNode *next;
}QNode,*QueuePtr;

typedef struct{     //對隊列的結構定義
    QueuePtr head;
    QueuePtr rear;
}LinkQueue; 

2.2、隊列初始化

  初始化主要是對為隊列中的兩個重要節點分配空間,這里我們需要注意的是初始化時頭指針和尾指針指向同一個節點。

  代碼如下:

status initQueue(LinkQueue* que) //初始化隊列
{
    que->head=que->rear=(QueuePtr)malloc(sizeof(QNode));
    if(!que->head)  //這段代碼對隊列里面的用戶自定義數據類型進行了初始化
        return ERROR;
    return OK;
}

2.3、入隊操作

  一定要搞清指針的概念。

  首先rear和head指向同一個元素。然后,我們使rear的next指向新元素,這樣rear指向的元素(即1)的next就是新元素了。最后,我們讓rear指向新元素。這樣一個入隊操作就完成了。

  

  代碼如下:

status enQueue(LinkQueue* que,QElemtype e)
{
    QueuePtr p = (QueuePtr)malloc(sizeof(QNode));
    if(!p) //若未能申請到空間,便退出
        return ERROR;
    p->data=e;
    p->next=NULL;

    que->rear->next = p;
    que->rear=p;
    return OK;
}

  

2.4、出隊操作

  我們來思考這個過程,在下圖隊列中,我們出隊的第一個元素是元素A,不是1。(因為1不是插入進來了的,而是我們初始化時就有的)。我們首先讓*t等於head的next,即元素A。然后修改head的next指向為元素A的next。

這樣head的next就會指向元素B。出隊操作就完成了。

  代碼如下:

status delQueue(LinkQueue* que,QElemtype *t)
{
    if(que->rear==que->head)
        return ERROR; //隊列為空

    QueuePtr p = que->head->next;
    *t=p->data;

    que->head->next=p->next;
    if(que->rear==p) //這個判斷是 確保在清空隊列的時候,讓rear指針歸位。
        que->rear=que->head;
    free(p);
    return OK;
}

  

2.5、回收隊列

  回收可以快速取消隊列,方法是讓頭尾碰面即可。

status destoryQueue(LinkQueue* que) //回收隊列
{
    if(que->head)
    {
        que->rear = que->head->next;
        free(que->head);
        que->head=que->rear;
    }
    return OK;
}

 

2.6、遍歷隊列和測試方法

  提供一個簡單的方法來測試鏈表隊列。

status viewQueue(LinkQueue* que)
{
    if(que->rear == que->head)
        return ERROR;
    
    QueuePtr p =que->head->next;
    while(p)
    {
        printf("val:%d",p->data);
        p=p->next;
    }
    return OK;
}

int main(int argc, char **argv)
{
    LinkQueue myQueue;
    initQueue(&myQueue);
    for(int i=1;i<=5;i++)
        enQueue(&myQueue,i);
    viewQueue(&myQueue);
    
    QElemtype a;
    for(int i=0;i<5;i++)
    {
        delQueue(&myQueue,&a);
        printf("%d\n",a);
    }
    destoryQueue(&myQueue);
    printf("fuck !");    
    return 0;
}    

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM