隊列的鏈式表示和實現


若用戶無法估計所用隊列的長度,則宜采用鏈隊列

鏈式隊列表示:如圖

 

 

Q.front 指向頭結點

Q.rear 指向尾結點

鏈隊列的類型定義:

#define MAXQSIZE 100 //最大隊列長度
typedef struct Qnode{
    // 數據域
    QElemType data;
    // 指針域
    // 棧是stack,所以是SNode
    // 隊列是 Queue,所以是QNode
    // 所指向結點仍然是 Qnode 這種類型
    stuct Qnode *next;
}QNode, *QuenPtr;

 

 

typedef struct{
    // 隊頭指針
    QueuePtr front;

    // 隊尾指針
    QueuePtr rear;

// 鏈式隊列
} LinkQueue;

 

 

鏈隊列運算指針的變化狀況

① 空隊列時,頭指針尾指針都指向一個結點,如圖:

 

 

② 元素 x 入隊列,Q.rear 只能指向隊尾

 

 

再有元素入隊,如下圖

 

 

 

③ 要出隊時,只能出 x ,不能直接出 y

 

 

 

------------------------------------------------------------------------------------------------------------------------------------------------

 

鏈隊列的操作——鏈隊列初始化

直接在內存當中找到一個頭結點,然后首尾指針都指向頭結點

#define MAXQSIZE 100 //最大隊列長度
typedef struct Qnode{
    // 數據域
    QElemType data;
    // 指針域
    // 棧是stack,所以是SNode
    // 隊列是 Queue,所以是QNode
    // 所指向結點仍然是 Qnode 這種類型
    stuct Qnode *next;
}QNode, *QuenPtr;


typedef struct{
    // 隊頭指針
    QueuePtr front;

    // 隊尾指針
    QueuePtr rear;

// 鏈式隊列
} LinkQueue;


Status InitQueue(LinkQueue &Q){

    Q.front = Q.rear = (QueuePtr)malloc(sizeof(QNode));

    // 加一個內存溢出判斷,防止出問題
    if(!Q.front){
        exit(OVERFLOW);
    }
    // next 域置空
    Q.front->next = NULL;
}

 

 

 

鏈隊列的操作——銷毀棧隊列

銷毀棧隊列就是從隊頭結點開始,依次釋放所有結點

Status DestroyQueue(LinkQueue &Q){
    while(Q.front){
        p = Q.front -> next;
        free(Q.front);
        Q.front = p;
        return OK; } }

 

或者使用如下代碼:

Status DestroyQueue(LinkQueue &Q){
    Q.rear = Q.front -> next;
    free(Q.front);
    Q.front = Q.rear;
    return OK;
}

 

 

鏈隊列的操作——將元素 e 入隊

鏈隊列入隊,只能在隊尾入,也就是從 an 后入隊

#define MAXQSIZE 100 //最大隊列長度
typedef struct Qnode{
    // 數據域
    QElemType data;
    // 指針域
    // 棧是stack,所以是SNode
    // 隊列是 Queue,所以是QNode
    // 所指向結點仍然是 Qnode 這種類型
    stuct Qnode *next;
}QNode, *QuenPtr;


typedef struct{
    // 隊頭指針
    QueuePtr front;

    // 隊尾指針
    QueuePtr rear;

// 鏈式隊列
} LinkQueue;

Status EnQueue(LinkQueue &Q, QElemType e){
    // 開辟一個內存空間
    p = (QueuePtr)malloc(sizeof(QNode));

    // 如果分配不成功,則直接退出
    if(!p){
        exit(OVERFLOW);
    }

    // 將 e 存入 p所指結點 的數據域,且將 P所指結點 
    p -> data = e;
    p -> next = NULL;

    // 尾指針所指結點的指針域修改,使其接上新添加的結點
    Q.rear -> next = p;

    // 修改尾指針所指向結點
    Q.rear = p;

    return OK;
}

 

 

鏈隊列的操作——鏈隊列出隊

鏈隊列的出隊是從隊頭出隊的,因此要刪掉頭結點后面的那個結點

 

直接修改前驅的指針域,就可以完成。最后再釋放掉

① new 一個指針p,使 指針p 指向頭結點后邊那個結點

    p = Q.fornt -> next;

② 修改 Q.front -> next ,使其原本指向出隊結點的指針域指向出隊結點后邊那個結點

    Q.front -> next = p -> next;

③ 釋放掉指針P

    用 C++ 就是 delete p;

    用 C 就是 free(p);

④ 假如需要知道出隊的元素是啥,就讓 e 存放並返回:

    e = p -> data;

具體代碼如下:

#define MAXQSIZE 100 //最大隊列長度
typedef struct Qnode{
    // 數據域
    QElemType data;
    // 指針域
    // 棧是stack,所以是SNode
    // 隊列是 Queue,所以是QNode
    // 所指向結點仍然是 Qnode 這種類型
    stuct Qnode *next;
}QNode, *QuenPtr;


typedef struct{
    // 隊頭指針
    QueuePtr front;

    // 隊尾指針
    QueuePtr rear;

// 鏈式隊列
} LinkQueue;

Status DeQueue(LinkQueue &Q, QElemType &e){
    
    // 判空
    if(Q.front == Q.rear){
        return ERROR;
    }

    p = Q.front -> next;
    e = p -> data;
    Q.front -> next = p -> next;
    
    // 如果刪除后,p 指針向后移動一個,下一個元素正好就是尾結點
    // 那么就不僅要修改頭結點的指針,也要修改尾指針
    if(Q.rear == p){
        Q.rear = Q.front;
    }

    delete p;
    return OK;
}

 

 

鏈隊列的操作——求鏈隊列的隊頭元素

#define MAXQSIZE 100 //最大隊列長度
typedef struct Qnode{
    // 數據域
    QElemType data;
    // 指針域
    // 棧是stack,所以是SNode
    // 隊列是 Queue,所以是QNode
    // 所指向結點仍然是 Qnode 這種類型
    stuct Qnode *next;
}QNode, *QuenPtr;


typedef struct{
    // 隊頭指針
    QueuePtr front;

    // 隊尾指針
    QueuePtr rear;

// 鏈式隊列
} LinkQueue;

// 求鏈隊列的隊頭元素
Status GetHead(LinkQueue Q, QElemType &e){
    if(Q.front == Q.rear){
        return ERRORl;
    }
    e = Q.front -> next -> data;
    return OK;
}

 


免責聲明!

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



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