數據結構(9)隊列之鏈隊列

前言

隊列同棧一樣,本質都是操作受限的線性表。與棧不同的是,隊列只允許在一端進行插入操作,在另一端進行刪除操作,允許插入的一端稱爲隊尾,允許刪除的一端稱爲隊頭。從線性表的角度來看,也就是說隊列只支持頭部刪除和尾部插入操作。它的特性就是先進先出,同生活中的排隊現象類似。

img_1

鏈隊列的初始化

只要認識到隊列的本質是線性表,那麼隊列的鏈式存儲和線性表的鏈式存儲都是一致的,都需要考慮頭結點的問題。如果設置了頭結點,那麼在初始化鏈隊列時就需要生成一個頭結點併爲它賦初值;如果不設頭結點則直接將隊列賦空即可。爲了方便操作,此處是設了頭結點的。

img_2

其他操作同單鏈表基本一致,就不寫了

源代碼

LinkQueue.h

#ifndef LinkQueue_h
#define LinkQueue_h

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

#define ElemType int

typedef struct QueueNode{
    ElemType data;
    struct QueueNode *next;
}QueueNode;

typedef struct LinkQueue{
    QueueNode *fount;
    QueueNode *tail;
}LinkQueue;

//初始化
void InitQueue(LinkQueue *Q);

//入隊
void EnQueue(LinkQueue *Q,ElemType x);
//出隊
void DeQueue(LinkQueue *Q);
//展示
void ShowQueue(LinkQueue *Q);
//獲取隊首元素
void GetHead(LinkQueue *Q,ElemType *x);
//獲取隊列長度
void GetLength(LinkQueue *Q);
//清除
void ClearQueue(LinkQueue *Q);
//摧毀
void DestoryQueue(LinkQueue *Q);
#endif /* LinkQueue_h */

LinkQueue.c


#include "LinkQueue.h"

//初始化
void InitQueue(LinkQueue *Q){
    //申請頭結點的空間
    QueueNode *s = (QueueNode *)malloc(sizeof(QueueNode));
    assert(s != NULL);
    
    //初始化值
    Q->fount = Q->tail = s;
    Q->tail->next = NULL;
}
//入隊->實際上就是尾部插入
void EnQueue(LinkQueue *Q,ElemType x){
    //申請新結點的空間並賦值
    QueueNode *s = (QueueNode *)malloc(sizeof(QueueNode));
    assert(s != NULL);
    s->data = x;
    s->next = NULL;
    
    //添加到隊列尾部
    Q->tail->next = s;
    //重新設置隊尾指針
    Q->tail = s;
}

//出隊->實際上就是頭部刪除
void DeQueue(LinkQueue *Q){
    //取出首元結點
    QueueNode *s = Q->fount->next;
    //判斷是否已空
    if (s != NULL) {
        Q->fount->next = s->next;
        free(s);
    }
    
    //判斷刪除的是否是最後一個結點
    if (Q->fount->next == NULL) {
        Q->tail = Q->fount;
        Q->tail->next = NULL;
    }
}

//展示
void ShowQueue(LinkQueue *Q){
    QueueNode *s = Q->fount->next;
    
    while (s != NULL) {
        printf("%4d",s->data);
        s = s->next;
    }
    printf("\n");
}

//獲取隊首元素
void GetHead(LinkQueue *Q,ElemType *x){
    if (Q->fount == Q->tail) {
        //隊列爲空,無法獲取
        printf("隊列已空\n");
        return;
    }
    
    QueueNode *s = Q->fount->next;
    *x = s->data;
}

//獲取隊列長度
void GetLength(LinkQueue *Q){
    int length = 0;
    QueueNode *s = Q->fount->next;
    while (s != NULL) {
        length ++;
        s = s->next;
    }
    printf("長度爲:%d\n",length);
}

//清除
void ClearQueue(LinkQueue *Q){
    QueueNode *s = Q->fount->next;
    while (s != NULL) {
        Q->fount->next = s->next;
        free(s);
        s = Q->fount->next;
    }
    Q->tail = Q->fount;
    Q->tail->next = NULL;
}
//摧毀
void DestoryQueue(LinkQueue *Q){
    ClearQueue(Q);
    free(Q->fount);
    Q->fount = Q->tail = NULL;
}

Main.c

#include "LinkQueue.h"

int main(int argc, const char * argv[]) {
    
    LinkQueue Q;
    InitQueue(&Q);
    
    //入隊
    for (int i = 0; i < 5; i ++) {
        EnQueue(&Q, i);
    }
    
    //展示
    ShowQueue(&Q);
    //出隊
    DeQueue(&Q);
    ShowQueue(&Q);
    //求長度
    GetLength(&Q);
    //清除
    ClearQueue(&Q);
    GetLength(&Q);
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章