1. 程式人生 > >資料結構學習心得——順序隊和鏈隊

資料結構學習心得——順序隊和鏈隊

佇列的定義

和棧相反佇列是一種先進先出的線性表。它只允許在表的一端進行插入,而在另一端刪除元素。這和我們日常生活中的排隊是一致的,最早進入佇列的元素最早離開。在佇列中,允許插入的一端叫做隊尾,允許刪除的一端叫做對頭。

順序隊和鏈隊

順序佇列是佇列的順序儲存結構,順序佇列實際上是運算受限的順序表。和順序表一樣,順序佇列用一個向量空間來存放當前佇列中的元素。由於佇列的隊頭和隊尾的位置是變化的,設定兩個指標front和rear分別指示隊頭元素和隊尾元素在向量空間中的位置,它們的初值在佇列初始化時均應設定為0。

這裡寫圖片描述

用連結串列表示的佇列簡稱為鏈隊,一個鏈隊顯然需要兩個分別只是對頭和隊尾的指標才能唯一確定。

這裡寫圖片描述

順序隊和鏈隊的程式碼實現

這裡注意順序隊我實現的是迴圈隊,注意迴圈佇列的隊空和隊滿的判斷上的不同。

#include <iostream>

using namespace std;
#define maxSize 20//巨集定義

//順序佇列的定義
typedef struct SqQueue
{
    int data[maxSize];
    int front;
    int rear;
}SqQueue;

//隊結點型別定義
typedef struct QNode
{
    int data;
    struct QNode *next;
}QNode;

//鏈隊的定義
typedef struct LiQueue { QNode *front; QNode *rear; }LiQueue; //順序佇列的初始化 void initSqQueue(SqQueue &q) { q.front = q.rear = 0; } //判斷順序佇列空 int isSqQueueEmpty(SqQueue q) { if(q.front == q.rear) { return 1; } else { return 0; } } //順序佇列入隊 int enSqQueue(SqQueue &q,int
x) { if((q.rear+1)%maxSize==q.front) { return 0; } else { q.rear = (q.rear + 1)%maxSize; q.data[q.rear] = x; return 1; } } //順序隊列出隊 int deSqQueue(SqQueue &q,int &x) { if(isSqQueueEmpty(q)) { return 0; } else { q.front = (q.front + 1)%maxSize; x = q.data[q.front]; return 1; } } //鏈隊初始化 void initQueue(LiQueue *&q) { q = new LiQueue; q->front=q->rear=NULL; } //判斷鏈隊為空 int isQueueEmpty(LiQueue *q) { //這裡注意q->front == q->rear不能判斷鏈隊為空,因為只有一個結點時也有q->front == q->rear if(q->front==NULL ||q->rear==NULL) { return 1; } else { return 0; } } //鏈隊入隊 void enQueue(LiQueue *&q,int x) { QNode *p = new QNode; p->data = x; p->next =NULL; if(q->rear==NULL) { q->front = q->rear = p; } else { q->rear->next = p; q->rear = p; } } //鏈隊出隊 int deQueue(LiQueue *&q,int &x) { QNode *p; if(isQueueEmpty(q)) { return 0; } //同樣注意q->front == q->rear的情況 if(q->front == q->rear) { p = q->front; x = p->data; q->front = q->rear = NULL; delete p; return 1; } else { p = q->front; q->front = p->next; x = p->data; delete p; return 1; } } int main() { cout << "Hello world!" << endl; return 0; }