鏈隊列的基本算法

1、介紹算法

隊列(Queue),計算機中一種經常使用的數據結構,具備先進先出FIFO的特色。數組

通俗一點,就跟生活中超市購物結帳排隊同樣,靠前的結帳先走,新來的排在後面等待。數據結構

對於隊列中的元素,通常都在隊頭出隊,在隊尾入隊,隊頭用Q.front表示,隊尾用Q.rear表示。函數

隊列的實現有兩種方式,經過數組或者鏈表實現。基於數組實現的隊列通常稱做順序隊列,基於鏈表實現的隊列通常稱做鏈式隊列。測試

鏈式隊列中,有兩個指針,分別是隊頭指針和隊尾指針。爲了操做方便,能夠給鏈隊列添加一個頭結點,並令頭指針指向頭結點。ui

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

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

 

2、示圖指針

 

3、算法code

#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);            //訪問隊列元素

4、代碼

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;
}

5、測試 

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;
}

 

6、打印

/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
相關文章
相關標籤/搜索