天天看點

資料結構——隊列

1.隊列的定義

​ 隊列是一種特殊的線性表,特殊之處在于它隻允許在表的前端(front)進行删除操作,而在表的後端(rear)進行插入操作,和棧一樣,隊列是一種操作受限制的線性表。進行插入操作的端稱為隊尾,進行删除操作的端稱為隊頭。

隊列儲存的圖像表示:

資料結構——隊列

2、隊列的基本運算

​ 1)初始化隊列:Init_Queue(q) ,初始條件:隊q 不存在。操作結果:構造了一個空隊;

​ 2)入隊操作: In_Queue(q,x),初始條件: 隊q 存在。操作結果: 對已存在的隊列q,插入一個元素x 到隊尾,隊發生變化;

​ 3)出隊操作: Out_Queue(q,x),初始條件: 隊q 存在且非空,操作結果: 删除隊首元素,并傳回其值,隊發生變化;

​ 4)讀隊頭元素:Front_Queue(q,x),初始條件: 隊q 存在且非空,操作結果: 讀隊頭元素,并傳回其值,隊不變;

​ 5)判隊空操作:Empty_Queue(q),初始條件: 隊q 存在,操作結果: 若q 為空隊則傳回為1,否則傳回為0。

3、隊列的順式儲存實作

​ 建立順序隊列結構必須為其靜态配置設定或動态申請一片連續的存儲空間,并設定兩個指針進行管理。一個是隊頭指針front,它指向隊頭元素;另一個是隊尾指針rear,它指向下一個入隊元素的存儲位置

順式儲存的圖示:

資料結構——隊列

(圖檔來源于百度:

https://baike.baidu.com/pic/%E9%98%9F%E5%88%97/14580481/0/cdbf6c81800a19d8116a4d8030fa828ba71e46ce?fr=lemma&ct=single#aid=0&pic=cdbf6c81800a19d8116a4d8030fa828ba71e46ce

順式隊列的存儲實作

#include <iostream>
#define MAXSIZE 100        //定義最大元素個數 
#define ElemType int        //定義資料類型 
#define ERROR 0
#define TRUE 1 
#define OVERFLOW -1

using namespace std;

typedef struct QNode *Queue;
struct QNode{
    ElemType Data[MAXSIZE];
    int rear;        //數組下标,表示最後一項
    int front;        //數組下标,表示第一項
};           

相信你學到隊列時,對順序表的插入和删除已經很熟練了,在這裡就不再贅述,重點在于下面的循環隊列!!!(如果不熟練可以看我另外的内容->本部落客.其他文章)

循環隊列的儲存實作

循環隊列的儲存圖示:

資料結構——隊列
https://baike.baidu.com/pic/%E5%BE%AA%E7%8E%AF%E9%98%9F%E5%88%97/3685773/1/5d6034a85edf8db1ee973ff60a23dd54574e74e2?fr=lemma#aid=1&pic=5d6034a85edf8db1ee973ff60a23dd54574e74e2

循環隊列的插入

void AddQueue(Queue Ptrq, ElemType X){
    if((Ptrq->rear+1)%MAXSIZE == Ptrq->front)        //用取餘判斷的是否隊列已滿
        cout << "Data overflow";
    Ptrq->rear = (Ptrq->rear+1)%MAXSIZE;
    //關于這裡為什麼要%MAXSIZE,這是循環的關鍵
    //如果後面add滿了,會從前面空出的位置繼續添加
    //此時rear所指向的數組下标應該為前面空出位置的下标
    //故%MAXSIZE
    
    Ptrq->Data[Ptrq->rear] = X;        //插入元素X
}           

循環隊列的删除

ElemType DeleteQueue(Queue Ptrq){
    if(Ptrq->front == Ptrq->rear){        //判斷是否為空隊列
        cout << "No data";
        return ERROR;
    }
    else{
        Ptrq->front = (Ptrq->front+1)%MAXSIZE;
        return Ptrq->Data[Ptrq->front];        //出清單
    }
}           

4、隊列的鍊式儲存實作

​ 隊列的鍊式存儲結構,其實就是線性表的單連結清單,隻不過它隻能尾進頭出而已,我們把它簡稱為鍊隊列。為了操作上的友善,我們将隊頭指針指向鍊隊列的頭節點,而隊尾指針指向終端節點。空隊列時,front和rear都指向頭節點。

鍊式隊列的圖示:

資料結構——隊列
https://baike.baidu.com/pic/%E9%98%9F%E5%88%97/14580481/0/7dd98d1001e939015d4345bb78ec54e737d196f6?fr=lemma&ct=single#aid=0&pic=7dd98d1001e939015d4345bb78ec54e737d196f6

鍊式隊列的儲存實作

#include <iostream>
#define MAXSIZE 100        //定義最大元素個數 
#define ElemType int        //定義資料類型 
#define ERROR 0
#define TRUE 1 
#define OVERFLOW -1

using namespace std;

typedef struct QNode *Queue;
struct QNode{
    ElemType Data;
    Queue Next;
};           

鍊式隊列的删除

ElementType DeleteQueue (Queue PtrQ ){
    Queue FrontCell;
    ElementType FrontElem;
    if (PtrQ->front == nullptr){        //判斷是否為空隊列
        cout << "No data";
        return ERROR;
    }
    FrontCell = PtrQ->front;
    if ( PtrQ->front == PtrQ->rear)        //如果隊列隻有一個元素 
        PtrQ->front = PtrQ->rear = nullptr;        //删除後隊列置為空
    else
        PtrQ->front = PtrQ->front->Next;
    FrontElem = FrontCell->Data;
    free(FrontCell);        //釋放被删除結點空間
    return FrontElem;
}           
下一篇: PKMS總結

繼續閱讀