鏈隊列的基本算法


一、介紹

隊列(Queue),計算機中一種常用的數據結構,具有先進先出FIFO的特點。

通俗一點,就跟生活中超市購物結賬排隊一樣,靠前的結賬先走,新來的排在后面等待。

對於隊列中的元素,一般都在隊頭出隊,在隊尾入隊,隊頭用Q.front表示,隊尾用Q.rear表示。

隊列的實現有兩種方式,通過數組或者鏈表實現。基於數組實現的隊列一般稱作順序隊列,基於鏈表實現的隊列一般稱作鏈式隊列。

鏈式隊列中,有兩個指針,分別是隊頭指針和隊尾指針。為了操作方便,可以給鏈隊列添加一個頭結點,並令頭指針指向頭結點。

空隊列判決條件:頭指針和尾指針均指向頭結點。也即Q.front == Q.rear。 

本文采用鏈表實現隊列,鏈隊列的操作即為單鏈表的插入和刪除的特殊情況,只是尚需修改尾指針或頭指針。

 

二、示圖

 

三、算法

#define QUEUE_OVERFLOW  -1
#define OK               1
#define ERROR            0
#define TRUE             1
#define FALSE            0

typedef int QElemType;
typedef int Status;

/// ----- 單鏈隊列 ------- 隊列的鏈式存儲結構
typedef struct QNode {
    QElemType  data;
    struct QNode *next;
}QNode, *QueuePtr;

typedef struct  {
    QueuePtr front; //隊頭指針
    QueuePtr rear;  //隊尾指針
}LinkQueue;

/// --- 基本操作的函數原型說明 -----
Status InitQueue(LinkQueue &Q);             //構造一個空的隊列Q
Status DestroyQueue(LinkQueue &Q);          //銷毀隊列Q,Q不再存在
Status ClearQueue(LinkQueue &Q);            //將隊列Q清空
Status QueueEmpty(LinkQueue  Q);            //判斷隊列Q是否為空,若空,返回TURE, 否則,返回FALSE
int    QueueLength(LinkQueue Q);            //返回Q的元素個數,也即隊列的長度
Status GetHead(LinkQueue Q, QElemType &e);  //若隊列Q不為空,則用e返回Q的隊頭元素,並返回OK;否則,返回ERROR
Status EnQueue(LinkQueue &Q, QElemType e);  //插入元素e為Q的新的隊尾元素
Status DeQueue(LinkQueue &Q, QElemType &e); //若隊列不空,則刪除Q的隊頭元素,用e返回其值,並返回OK,否則,返回ERROR
void   QueueVisit(LinkQueue &Q);            //訪問隊列元素

四、代碼

Status InitQueue(LinkQueue &Q) {

    //構造一個空隊列Q
    Q.front = Q.rear = (QueuePtr)malloc(sizeof(QNode));
    if (!Q.front) exit(QUEUE_OVERFLOW); //存儲分配失敗
    Q.front->next = NULL;

    return OK;
}

Status DestroyQueue(LinkQueue &Q){

    //銷毀隊列Q
    while (Q.front){
        Q.rear = Q.front->next;
        free(Q.front); //從隊頭取出每一個元素並釋放內存,Q.rear作為一個臨時指針使用
        Q.front = Q.rear;
    }
    cout<<"隊列已銷毀"<<endl;
    return OK;
}

Status ClearQueue(LinkQueue &Q){

    //清空隊列Q
    Q.rear = Q.front;
    cout<<"隊列已清空"<<endl;
    return OK;
}

Status QueueEmpty(LinkQueue Q){

    //判斷隊列Q是否為空
    if (Q.front == Q.rear) {
        cout<<"隊列為空"<<endl;
        return TRUE;
    }
    cout<<"隊列不為空"<<endl;
    return FALSE;
}

int QueueLength(LinkQueue Q){

    //獲取隊列的長度
    QNode *p = Q.front->next;
    int len = 0;
    while (p){
        len++;
        p = p->next;
    }
    cout<<"隊列長度:"<<len<<endl;
    return len;
}

Status GetHead(LinkQueue Q, QElemType &e){

    //獲取隊頭元素
    if (Q.front == Q.rear) {
        return FALSE;
    }
    QNode *p = Q.front->next;
    e = p->data;
    cout<<"隊頭元素:"<<e<<endl;
    return OK;
}

Status EnQueue(LinkQueue &Q, QElemType e){

    //插入元素e為Q的新的隊尾元素
    QNode *p = (QueuePtr)malloc(sizeof(QNode));
    if (!p) exit(QUEUE_OVERFLOW);
    p->data = e;
    p->next = NULL;
    Q.rear->next = p;//當前隊尾指針的next指針指向新元素
    Q.rear = p;//修改隊尾指針
    cout<<"入隊:"<<e<<endl;
    return OK;
}

Status DeQueue(LinkQueue &Q, QElemType &e){

    //刪除隊頭元素
    if (Q.front == Q.rear) return ERROR;
    QNode *p = Q.front->next;
    e = p->data;
    Q.front->next = p->next;
    cout<<"出隊:"<<e<<endl;
    if (Q.rear == p) {
        Q.rear = Q.front;
    }
    free(p);
    return OK;
}

void QueueVisit(LinkQueue &Q){

    if (Q.front == Q.rear){
        cout<<"隊列為空"<<endl;
        return;
    }

    //訪問隊列元素
    QNode *p = Q.front->next;
    printf("隊列順序為:");
    while (p){
        QElemType e = p->data;
        p = p->next;
        printf("%d ",e);
    }
    cout<<endl;
}

五、測試 

int main() {

    //構造隊列
    LinkQueue queue;
    if (InitQueue(queue) == OK){
        for (int i = 1; i <= 10; ++i) {
            EnQueue(queue,i);//入隊列
        }
    }

    //判斷隊列是否為空
    QueueEmpty(queue);

    //訪問隊列元素
    QueueVisit(queue);

    //獲取隊列長度
    QueueLength(queue);

    //獲取隊頭元素
    QElemType e;
    GetHead(queue, e);

    //出隊列
    for (int i=1; i<5 ; i++) {
        DeQueue(queue, e);
    }
    QueueVisit(queue);

    //清空隊列
    ClearQueue(queue);
    QueueEmpty(queue);

    //銷毀隊列
    DestroyQueue(queue);

    return 0;
}

 

六、打印

/Users/xiayuanquan/CLionProjects/queueTest/cmake-build-debug/queueTest
入隊:1
入隊:2
入隊:3
入隊:4
入隊:5
入隊:6
入隊:7
入隊:8
入隊:9
入隊:10
隊列不為空
隊列順序為:1 2 3 4 5 6 7 8 9 10 
隊列長度:10
隊頭元素:1
出隊:1
出隊:2
出隊:3
出隊:4
隊列順序為:5 6 7 8 9 10 
隊列已清空
隊列為空
隊列已銷毀

進程已結束,退出代碼 0

 


免責聲明!

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



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