鏈式存儲隊列

隊列的鏈式存儲結構,簡單看來和線性表的單鏈表很是類似,只不過,鏈式存儲的隊列,只能夠在隊尾rear入隊,隊頭front出隊。bash

一樣爲了方便,在隊列前添加頭結點。markdown

   1.1 鏈式存儲隊列結構設計:spa

// 結點結構
typedef struct QNode{
    QElemType data;
    struct QNode *next;
}QNode,*QListNode;
// 隊列鏈表結構
typedef struct {
    QListNode front; // 隊頭
    QListNode rear;  // 隊尾
}SqQueue;
複製代碼
   1.2 初始化隊列 

將隊列的front,rear都指向新建的頭結點。設計


// 初始化
Status InitQueue(SqQueue *Q){    
    Q->front = Q->rear = (QListNode)malloc(sizeof(QListNode));
    if (!Q->front) {
        return ERROR;
    }
    Q->front->next = NULL;  // 頭結點的指針域置空 此處Q->rear的next一樣指向空
    return OK;
}

複製代碼


   1.3 添加入隊,只須要調整rear就能夠,front始終指向頭結點。指針


// 添加元素
Status EnterQueue(SqQueue *Q,QElemType e){
    
    if (!Q) {
        return ERROR;
    }
    
    QListNode temp = (QListNode)malloc(sizeof(QNode));
    if (!temp) {
        return ERROR;
    }
    temp->data = e;
    temp->next = NULL;  // 要將新結點的next指向空,以避免髒數據
    
    Q->rear->next = temp;
    Q->rear = temp;     // 調整rear 指向最新的結點
    return OK;
}


複製代碼


   1.4 刪除出隊code

刪除要注意兩個條件:orm

  • 刪除前判斷隊列是不是空的
  • 判斷要刪除的是否是最後一個元素


// 刪除
Status DeleteQueue(SqQueue *Q,QElemType *e){
    if (!Q) {
        return ERROR;
    }
    if (Q->front == Q->rear) {  // 判斷是否爲空
        printf("隊列已空\n");
        return ERROR;
    }

    QListNode temp = Q->front->next;
    *e = temp->data;
    Q->front->next = temp->next; // 要把頭結點的next指向要刪除結點的next
    
    if (Q->rear == temp) {   // 假如要刪除的是最後一個,要把rear指向頭結點
        Q->rear = Q->front;
    }
    
    free(temp);    
    return OK;
}

複製代碼


   1.5 遍歷全部元素隊列

// 遍歷
Status QueueTrave(SqQueue Q){

    QListNode temp = Q.front->next;
    while (temp) {
        printf("%d ",temp->data);
        temp = temp->next;
    }
    printf("\n");
    
    return OK;
}

複製代碼


   1.6 隊列長度it

經過遍歷每個結點,計算遍歷的次數,來獲取隊列的長度。io

獲取隊列長度也能夠在設計隊列時,添加count,每次入列出列進行count加減

// 隊列長度  
int QueueLength(SqQueue Q){
    if (Q.front != Q.rear) {
        QListNode temp = Q.front->next;
        int count = 0;
        while (temp) {
            count++;
            temp = temp->next;
        }
        return count;
    }
    return 0;
}

複製代碼


   1.7 隊列清空

  1. 將rear從新指向頭結點
  2. 遍歷全部的結點,free掉
  3. 將front的next指向爲null

// 清空
Status ClearQueue(SqQueue *Q){
    if (!Q) {
        return ERROR;
    }
    
    if (Q->front == Q->rear) { // 判斷隊列是否爲空
        return ERROR;
    }
    Q->rear = Q->front;  
    
    QListNode temp = Q->front->next;
    while (temp) {
        QListNode p = temp->next;
        free(temp);
        temp = p;
    }
    
    Q->front->next = NULL;
    return OK;
}

複製代碼


   1.8 銷燬隊列

// 銷燬
Status DestoryQueue(SqQueue *Q){
    
    QListNode temp = Q->front;
    while (temp) {
        QListNode p = temp->next;
        free(temp);
        temp = p;
    }
    
    /*  銷燬不用在乎front rear ,因此也能夠不用太多其它的參數,以下
    while (Q->front) {
        Q->rear = Q->front->next;
        free(Q->front);
        Q->front = Q->rear;
    }*/
    
    return OK;
}

複製代碼
相關文章
相關標籤/搜索