3. 線性結構--隊列

隊列

定義

具有一定操作約束的線性表,只能在一端插入,而在另一端刪除

  • 數據插入:入隊列(AddQ)
  • 數據刪除:出隊列(DeleteQ)、
  • 先來先服務
  • 先進先出:FIFO

抽象數據類型描述

  • 類型名稱:隊列(Queue)
  • 數據對象集:一個有0個或多個元素的有窮線性表
  • 操作集:長度爲MaxSize的隊列QQueue ,隊列元素itemElementType
    1. Queue CreatQueue(int MaxSize):生成長度爲MaxSize的空隊列
    2. int IsFull(Queue Q, int MaxSize):判斷隊列Q是否已滿
    3. void AddQ(Queue Q, ElementType item):將數據元素item插入隊列Q
    4. int isEmptyQ(Queue Q):判斷隊列Q是否爲空
    5. ElementType DeleteQ(Queue Q):將隊頭數據元素從隊列中刪除並返回

順序存儲實現

隊列的順序存儲結構通常由一個一維數組和一個記錄隊列頭元素位置的變量front以及一個記錄隊列胃元素位置的變量rear組成

循環隊列

在使用一維數組進行隊列的存儲時,通常會實現爲循環隊列,這時需要考慮如何判斷隊列空或滿的情況:
* 使用額外的標記:Size或者Tag域
* 僅使用n-1個數組空間

結構定義

#define MaxSize<存儲數據元素的最大個數>
struct QNode {
    ElementType Data[MaxSize];
    int rear;
    int front;
};
typedef struct QNode *Queue;

主要操作

front和rear指針的移動採用“加1取餘”法,體現了順序存儲的“循環使用”

入隊列

void AddQ(Queue PtrQ, ElementType item) {
    if ((PtrQ->rear + 1) % MaxSize == PtrQ->front) {
        printf("隊列滿");
        return;
    }

    PtrQ->rear = (PtrQ->rear + 1) % MaxSize;
    PtrQ->Data[PtrQ->rear] = item;
}

出隊列

ElementType DeleteQ(Queue PtrQ) {
    if (PtrQ->front == PtrQ->rear) {
        printf("隊列空");
        return ERROR;
    }

    PtrQ->front = (PtrQ->front + 1) % MaxSize;
    return PtrQ->Data[PtrQ->front];
}

鏈式存儲實現

隊列的鏈式存儲結構也可以用一個單鏈表實現。插入和刪除操作分別在鏈表的兩頭進行。

  • front指向鏈表頭
  • rear指向鏈表尾

結構定義

struct Node {
    ElementType Data;
    struct Node *Next;
};
struct QNode {      // 鏈隊列結構
    struct Node *rear;  // 指向隊尾結點
    struct Node *front; // 指向隊頭結點
};
typedef struct QNode *Queue;
Queue PtrQ;

image

主要操作

以不帶頭結點的鏈式隊列爲例

入隊列

void AddQ(Queue PtrQ, ElementType item) {
    struct Node *ele = (struct Node*)malloc(sizeof(struct Node));
    ele->Data = item;
    if (PtrQ->rear == NULL && PtrQ->front == NULL) {    // 說明這是一個空隊列
        PtrQ->rear = PtrQ->front = ele;
    } else {
        PtrQ->rear->Next = ele;
        PtrQ->rear = PtrQ->rear->Next;
    }

}

出隊列

ElementType DeleteQ(Queue PtrQ) {
    struct Node *FrontCell;
    ElementType FrontElem;

    if (PtrQ->front == NULL) {
        printf("隊列空");
        return ERROR;
    }

    FrontCell = PtrQ->front;
    if (PtrQ->front == PtrQ->rear) {    // 若隊列只有一個元素
        PtrQ->front = PtrQ->rear = NULL;    // 刪除後隊列置爲空
    } else {
        PtrQ->front = PtrQ->front->Next;
    }
    FrontElem = FrontCell->Data;
    free(FrontCell);

    return FrontElem;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章