1. 程式人生 > >迴圈佇列(順序表實現,連結串列實現)

迴圈佇列(順序表實現,連結串列實現)

迴圈佇列

迴圈佇列是將順序佇列變為一個變成一個環狀的空間。頭尾指標以及佇列元素之間的關係不變,只是在迴圈佇列中,頭尾指標“依環狀增 1”的操作可用”模“運算來實現。通過取模運算,頭指標和尾指標就可以在順序表空間內以頭尾銜接的方式迴圈移動。

隊空條件:Q.front == Q.rear

隊滿條件:(Q.rear + 1)% MAXQSIZE == Q.rear(少用一個元素空間,即佇列空間為m時,有m-1個元素就認為是隊滿)。

迴圈佇列(順序表實現)

#include <bits/stdc++.h>
#define MAXQSIZE 100 ///佇列可能到達的最大長度
#define OK 1
#define ERROR 0
using namespace std;

typedef int QElemType;
typedef int Status;
typedef struct
{
    QElemType *base; ///儲存空間的基地址
    int front; ///頭指標
    int rear; ///尾指標
}SqQueue;

Status InitQueue(SqQueue &Q) ///迴圈佇列的初始化
{
    Q.base = new QElemType[MAXQSIZE]; ///為佇列分配一個最大容量為MAXQSIZE的陣列空間
    if(!Q.base) exit(OVERFLOW); ///儲存記憶體失敗
    Q.front = Q.rear = 0; ///頭指標和尾指標置為0,佇列為空
    return OK;
}

int QueueLength(SqQueue Q) ///迴圈佇列的長度
{///返回Q的元素個數,即佇列的長度
    return (Q.rear-Q.front+MAXQSIZE)%MAXQSIZE;
}

Status EnQueue(SqQueue &Q, QElemType e) ///佇列入隊
{///插入元素e為Q的新的隊尾元素
    if( (Q.rear+1)%MAXQSIZE == Q.front) return ERROR; ///尾指標在迴圈意義上加一等於頭指標,表明隊滿
    Q.base[Q.rear] = e; ///新元素插入隊尾
    Q.rear = (Q.rear+1)%MAXQSIZE; ///隊尾指標加1
    return OK;
}

Status DeQueue(SqQueue &Q, QElemType &e) ///迴圈佇列的出隊
{///刪除Q的隊頭元素,用e返回其值
    if(Q.front == Q.rear) return ERROR; ///隊空
    e = Q.base[Q.front]; ///儲存隊頭元素
    Q.front = (Q.front+1)%MAXQSIZE; ///隊頭元素加1
    return OK;
}

QElemType GetHead(SqQueue Q) ///取迴圈佇列的隊頭元素
{///返回佇列的隊頭元素,不修改頭指標
    if(Q.front != Q.rear) return Q.base[Q.front]; ///佇列非空
}
void Travel(SqQueue Q) ///遍歷佇列
{
    int x = Q.front;
    while(x != Q.rear)
    {
        cout<< Q.base[x] << " ";
        x++;
        x %= MAXQSIZE;
    }
    cout<< endl << endl;
}
int main()
{
    SqQueue Q;
    QElemType e;
    cout<< "1. 建立佇列" << endl;
    cout<< "2. 入隊" << endl;
    cout<< "3. 出隊" << endl;
    cout<< "4. 隊頭元素" << endl;
    cout<< "5. 佇列長度" << endl;
    cout<< "6. 遍歷佇列" << endl;
    int choose = -1;
    while(choose)
    {
        cout<< "請選擇:";
        cin>> choose;
        switch(choose)
        {
            case 1:
            {
                if(InitQueue(Q)) cout<< "佇列建立成功!\n\n";
                else cout<< "佇列建立失敗\n\n";
            }
            break;
            case 2:
            {
                cout<< "請輸入入隊元素:";
                cin>>e;
                if(EnQueue(Q, e)) cout<< "入隊成功!\n\n";
                else cout<< "入隊失敗!\n\n";
            }
            break;
            case 3:
            {
                if(DeQueue(Q, e)) cout<< "出隊元素為: " << e << endl << endl;
                else cout<< "出隊失敗!\n\n";
            }
            break;
            case 4:
            {
                if(Q.front == Q.rear) cout<< "佇列為空!\n\n";
                else cout<< "隊頭元素為:" << GetHead(Q) << endl << endl;
            }
            break;
            case 5:
            {
                cout<< "佇列長度為:" << QueueLength(Q) << endl << endl;
            }
            break;
            case 6:
            {
                Travel(Q);
            }
        }
    }
    return 0;
}

迴圈佇列(連結串列實現) 

用帶有頭結點的單鏈表儲存結構實現佇列。 

#include <bits/stdc++.h>
#define OK 1
#define ERROR -1
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef int Status;
typedef int QElemType;
typedef struct QNode ///佇列的儲存結構
{
    QElemType data;
    struct QNode *next;
}QNode, *QueuePtr;
typedef struct
{
    QueuePtr front; /// 隊頭指標
    QueuePtr rear; /// 隊尾指標
}LinkQueue;
QueuePtr p;
int length = 0;
Status InitQueue(LinkQueue &Q) ///構造一個空佇列
{
    Q.front = Q.rear = new QNode; ///生成新結點作為頭結點,隊頭和隊尾指標都指向此節點
    Q.front -> next = NULL; ///頭結點指標置為空域
    length = 0;
    return OK;
}

Status EnQueue(LinkQueue &Q, QElemType e) ///插入元素e為Q的新的隊尾元素
{///和順序迴圈佇列入隊操作不同的是,鏈隊在入隊前不需要判斷隊是否滿,而是需要為入隊
 ///元素分配一個結點空間
    p = new QNode; ///為入隊元素分配結點空間,用指標p指向
    p->data = e; ///將新結點資料域置為e
    p->next = NULL; Q.rear->next = p; ///將新結點插入到隊尾
    Q.rear = p; ///修改隊尾指標
    length++;
    return OK;
}
Status DeQueue(LinkQueue &Q, QElemType &e) ///刪除Q的隊頭元素,用e返回其值
{
    if(Q.front == Q.rear) return ERROR; /// 若佇列為空,返回ERROR
    p = Q.front->next;  /// p指向隊頭元素
    e = p->data; ///e儲存隊頭元素的值
    Q.front->next = p->next; ///修改頭結點的指標域
    if(Q.rear == p) Q.rear = Q.front; ///最後一個元素被刪,隊尾指標指向頭結點
    delete p; ///釋放原頭元素的空間
    length--;
    return OK;
}
QElemType GetHead(LinkQueue Q) ///返回Q的隊頭元素,不修改隊頭指標
{
    if(Q.front != Q.rear) return Q.front->next->data; ///返回隊頭元素的值,隊頭指標不變
}
void Travel(LinkQueue Q)
{
    if(Q.front == Q.rear) return ;
    p = Q.front->next;
    while(1)
    {
        cout<< p->data << " ";
        if(p==Q.rear) break;
        p = p->next;
    }
    cout<< endl << endl;
}
int main()
{
    LinkQueue Q;
    QElemType e;
    cout<< "1. 建立佇列" << endl;
    cout<< "2. 入隊" << endl;
    cout<< "3. 出隊" << endl;
    cout<< "4. 隊頭元素" << endl;
    cout<< "5. 佇列長度" << endl;
    cout<< "6. 遍歷佇列" << endl;
    int choose = -1;
    while(choose)
    {
        cout<< "請選擇:";
        cin>> choose;
        switch(choose)
        {
            case 1:
            {
                if(InitQueue(Q)) cout<< "佇列建立成功!\n\n";
                else cout<< "佇列建立失敗\n\n";
            }
            break;
            case 2:
            {
                cout<< "請輸入入隊元素:";
                cin>>e;
                if(EnQueue(Q, e)) cout<< "入隊成功!\n\n";
                else cout<< "入隊失敗!\n\n";
            }
            break;
            case 3:
            {
                if(DeQueue(Q, e)) cout<< "出隊元素為: " << e << endl << endl;
                else cout<< "出隊失敗!\n\n";
            }
            break;
            case 4:
            {
                if(Q.front == Q.rear) cout<< "佇列為空!\n\n";
                else cout<< "隊頭元素為:" << GetHead(Q) << endl << endl;
            }
            break;
            case 5:
            {
                cout<< "佇列長度為:" << length << endl << endl;
            }
            break;
            case 6:
            {
                Travel(Q);
            }
        }
    }
    return 0;
}