本文已經過時, 最新的重構文章請點擊 : 《【資料結構 – 重構】雙向佇列 (雙端佇列) [上篇]》

雙向佇列是一種限定的線型結構. 儘管名字中存在佇列, 但實際並不是佇列. 它是一種同時具有佇列和堆疊性質的抽象數據類型. 它可以同時在前端或者後端插入或者彈出. 當然, 所有的操控都限於兩端

在實際的應用中, 除去不受限制的雙向佇列, 還有彈出受限制的雙向佇列和插入受限制的雙向佇列

  • 輸出受限制 : 一端只允許插入, 另一端允許插入或者彈出
  • 輸入受限制 : 一端只允許彈出, 另外一端允許插入和彈出
  • 不受限制 : 兩頓都允許插入和彈出

不受限制的雙向佇列, 前端禁止操控即是一個堆疊, 當然實際運用到雙向佇列的話, 基本不會這樣去禁止, 因為可以直接用 stack 來處理

我在寫雙向佇列的時候, 將情況分為 5 種 :

  1. 前端彈出受限制
  2. 前端插入受限制
  3. 後端彈出受限制
  4. 後端插入受限制
  5. 兩端都不受限制

這些都可以通過一個類別和不同的選單去完成. 當然, 你可以使用不同的類別和同一個選單和提示完成

我們使用一張 SVG 圖像來表示雙向佇列

在本次的代碼中, 使用到了 STL (C++ 的標準程式庫) 中的 vector. 因為如果使用陣列來表示 Deque 的話, 程式碼會顯得很繁瑣. 並且這次並沒有使用註解, 因為代碼形式和之前的差別不大


下面是本人寫的原始碼

如若有錯誤存在, 可以聯絡我或者直接添加評論. 關於原始碼的註解, 已經給的比較全面, 還有不明白的可以直接評論, 對於註解的建議也可以提出. 直接讀原始碼的函式名稱或者變數名稱可以直接了解作用

Deque.hpp :

#ifndef DEQUE_DEQUE_HPP
#define DEQUE_DEQUE_HPP

#include <iostream>
#include <cstdlib>
#include <vector>

namespace Deque {
    using std::cin;
    using std::cout;
    using std::endl;
    using std::vector;
    class Queue {
    private :
        bool isEmpty();
    protected :
        vector<int> vec;
    public :
        Queue();
        ~Queue();
        long long int getFirst();
        long long int getLast();
        void firstEnter(int data);
        void lastEnter(int data);
        void firstOut();
        void lastOut();
        void clearDeque();
        void clearVector();
        void showDeque();
    };
}

#endif //DEQUE_DEQUE_HPP

Deque.cpp :

#include "Deque.hpp"

using namespace Deque;

Queue::Queue() {

}
Queue::~Queue() {

}
bool Queue::isEmpty() {
    if(this->vec.empty()) {
        return true;
    }
    return false;
}
long long int Queue::getFirst() {
    if(this->isEmpty()) {
        return INT64_MIN;
    }
    return (long long int)this->vec.front();
}
long long int Queue::getLast() {
    if(this->isEmpty()) {
        return INT64_MIN;
    }
    return (long long int)this->vec.back();
}
void Queue::firstEnter(int data) {
    this->vec.insert(this->vec.begin(), data);
}
void Queue::lastEnter(int data) {
    this->vec.push_back(data);
}
void Queue::firstOut() {
    if(this->isEmpty()) {
        cout << "The deque is empty!" << endl;
        cout << "Press any key to continue!" << endl;
        getchar();
        getchar();
        return;
    }
    cout << "The element : " << this->vec.front() << " has been out!" << endl;
    this->vec.erase(this->vec.begin());
    cout << "Press any key to continue!" << endl;
    getchar();
    getchar();
}
void Queue::lastOut() {
    if(this->isEmpty()) {
        cout << "The deque is empty!" << endl;
        cout << "Press any key to continue!" << endl;
        getchar();
        getchar();
        return;
    }
    cout << "The element : " << this->vec.back() << " has been out!" << endl;
    this->vec.pop_back();
    cout << "Press any key to continue!" << endl;
    getchar();
    getchar();
}
void Queue::clearDeque() {
    this->vec.clear();
}
void Queue::clearVector() {
    vector<int> tempVector;
    tempVector.swap(this->vec);
}
void Queue::showDeque() {
    if(this->isEmpty()) {
        return;
    }
    int size = this->vec.size();
    cout << "Index : \t";
    for(int i = 1; i <= size; i++) {
        cout << i << "\t";
    }
    cout << endl << "Element : \t";
    for(vector<int>::iterator iterator = this->vec.begin(); iterator < this->vec.end(); iterator++) {
        cout << *iterator << "\t";
    }
    cout << endl;
}

main.cpp :

#include "Deque.hpp"

#define UNLIMITED_QUEUE 1
#define FIRST_OUT_LIMITED_QUEUE 2
#define FIRST_ENTER_LIMITED_QUEUE 3
#define LAST_OUT_LIMITED_QUEUE 4
#define LAST_ENTER_LIMITED_QUEUE 5

using namespace Deque;

void unlimitedQueueMenu();
void unlimitedQueueLoop(Queue *deque);
void firstOutLimitedQueueMenu();
void firstOutLimitedQueueLoop(Queue *deque);
void firstEnterLimitedQueueMenu();
void firstEnterLimitedQueueLoop(Queue *deque);
void lastOutLimitedQueueMenu();
void lastOutLimitedQueueLoop(Queue *deque);
void lastEnterLimitedQueueMenu();
void lastEnterLimitedQueueLoop(Queue *deque);

int main(int argc, char *argv[]) {
    int choice;
    auto *deque = new Queue;
    cout << "-------------------------------------" << endl;
    cout << "1. Unlimited Queue" << endl;
    cout << "2. First Out Limited Queue" << endl;
    cout << "3. First Enter Limited Queue" << endl;
    cout << "4. Last Out Limited Queue" << endl;
    cout << "5. Last Enter Limited Queue" << endl;
    cout << "-------------------------------------" << endl;
    cout << "Please choose what queue you want to use : ";
    cin >> choice;
    switch(choice) {
        case UNLIMITED_QUEUE :
            unlimitedQueueLoop(deque);
            break;
        case FIRST_OUT_LIMITED_QUEUE :
            firstOutLimitedQueueLoop(deque);
            break;
        case FIRST_ENTER_LIMITED_QUEUE :
            firstEnterLimitedQueueLoop(deque);
            break;
        case LAST_OUT_LIMITED_QUEUE :
            lastOutLimitedQueueLoop(deque);
            break;
        case LAST_ENTER_LIMITED_QUEUE :
            lastEnterLimitedQueueLoop(deque);
            break;
        default :
            break;
    }
}
void unlimitedQueueMenu() {
    cout << "-------------------------------------" << endl;
    cout << "1. Get the first element." << endl;
    cout << "2. Get the last element." << endl;
    cout << "3. First enter." << endl;
    cout << "4. Last enter." << endl;
    cout << "5. First out." << endl;
    cout << "6. Last out." << endl;
    cout << "7. Clear the deque." << endl;
    cout << "8. Exit." << endl;
    cout << "-------------------------------------" << endl;
    cout << "Please enter your choice : ";
}
void unlimitedQueueLoop(Queue *deque) {
    int choice;
    long long int dataGet;
    int data;
    do {
        system("clear");
        deque->showDeque();
        unlimitedQueueMenu();
        cin >> choice;
        switch(choice) {
            case 1 :
                dataGet = deque->getFirst();
                if(dataGet == INT64_MIN) {
                    cout << "The deque is empty!" << endl;
                    cout << "Press any key to continue!" << endl;
                }else {
                    cout << "The first element : " << dataGet << endl;
                    cout << "Press any key to continue!" << endl;
                }
                getchar();
                getchar();
                break;
            case 2 :
                dataGet = deque->getLast();
                if(dataGet == INT64_MIN) {
                    cout << "The deque is empty!" << endl;
                    cout << "Press any key to continue!" << endl;
                }else {
                    cout << "The first element : " << dataGet << endl;
                    cout << "Press any key to continue!" << endl;
                }
                getchar();
                getchar();
                break;
            case 3 :
                cout << "Please enter the element you want to enter : ";
                cin >> data;
                deque->firstEnter(data);
                break;
            case 4 :
                cout << "Please enter the element you want to enter : ";
                cin >> data;
                deque->lastEnter(data);
                break;
            case 5 :
                deque->firstOut();
                break;
            case 6 :
                deque->lastOut();
                break;
            case 7 :
                deque->clearDeque();
                break;
            case 8 :
                deque->clearVector();
                delete deque;
                exit(0);
            default :
                break;
        }
    }while(choice != 8);
}
void firstOutLimitedQueueMenu() {
    cout << "-------------------------------------" << endl;
    cout << "1. Get the first element." << endl;
    cout << "2. Get the last element." << endl;
    cout << "3. First enter." << endl;
    cout << "4. Last enter." << endl;
    cout << "5. Last out." << endl;
    cout << "6. Clear the deque." << endl;
    cout << "7. Exit." << endl;
    cout << "-------------------------------------" << endl;
    cout << "Please enter your choice : ";
}
void firstOutLimitedQueueLoop(Queue *deque) {
    int choice;
    long long int dataGet;
    int data;
    do {
        system("clear");
        deque->showDeque();
        firstOutLimitedQueueMenu();
        cin >> choice;
        switch(choice) {
            case 1 :
                dataGet = deque->getFirst();
                if(dataGet == INT64_MIN) {
                    cout << "The deque is empty!" << endl;
                    cout << "Press any key to continue!" << endl;
                }else {
                    cout << "The first element : " << dataGet << endl;
                    cout << "Press any key to continue!" << endl;
                }
                getchar();
                getchar();
                break;
            case 2 :
                dataGet = deque->getLast();
                if(dataGet == INT64_MIN) {
                    cout << "The deque is empty!" << endl;
                    cout << "Press any key to continue!" << endl;
                }else {
                    cout << "The first element : " << dataGet << endl;
                    cout << "Press any key to continue!" << endl;
                }
                getchar();
                getchar();
                break;
            case 3 :
                cout << "Please enter the element you want to enter : ";
                cin >> data;
                deque->firstEnter(data);
                break;
            case 4 :
                cout << "Please enter the element you want to enter : ";
                cin >> data;
                deque->lastEnter(data);
                break;
            case 5 :
                deque->lastOut();
                break;
            case 6 :
                deque->clearDeque();
                break;
            case 7 :
                deque->clearVector();
                delete deque;
                exit(0);
            default :
                break;
        }
    }while(choice != 7);
}
void firstEnterLimitedQueueMenu() {
    cout << "-------------------------------------" << endl;
    cout << "1. Get the first element." << endl;
    cout << "2. Get the last element." << endl;
    cout << "3. Last enter." << endl;
    cout << "4. First out." << endl;
    cout << "5. Last out." << endl;
    cout << "6. Clear the deque." << endl;
    cout << "7. Exit." << endl;
    cout << "-------------------------------------" << endl;
    cout << "Please enter your choice : ";
}
void firstEnterLimitedQueueLoop(Queue *deque) {
    int choice;
    long long int dataGet;
    int data;
    do {
        system("clear");
        deque->showDeque();
        firstEnterLimitedQueueMenu();
        cin >> choice;
        switch(choice) {
            case 1 :
                dataGet = deque->getFirst();
                if(dataGet == INT64_MIN) {
                    cout << "The deque is empty!" << endl;
                    cout << "Press any key to continue!" << endl;
                }else {
                    cout << "The first element : " << dataGet << endl;
                    cout << "Press any key to continue!" << endl;
                }
                getchar();
                getchar();
                break;
            case 2 :
                dataGet = deque->getLast();
                if(dataGet == INT64_MIN) {
                    cout << "The deque is empty!" << endl;
                    cout << "Press any key to continue!" << endl;
                }else {
                    cout << "The first element : " << dataGet << endl;
                    cout << "Press any key to continue!" << endl;
                }
                getchar();
                getchar();
                break;
            case 3 :
                cout << "Please enter the element you want to enter : ";
                cin >> data;
                deque->lastEnter(data);
                break;
            case 4 :
                deque->firstOut();
                break;
            case 5 :
                deque->lastOut();
                break;
            case 6 :
                deque->clearDeque();
                break;
            case 7 :
                deque->clearVector();
                delete deque;
                exit(0);
            default :
                break;
        }
    }while(choice != 7);
}
void lastOutLimitedQueueMenu() {
    cout << "-------------------------------------" << endl;
    cout << "1. Get the first element." << endl;
    cout << "2. Get the last element." << endl;
    cout << "3. First enter." << endl;
    cout << "4. Last enter." << endl;
    cout << "5. First out." << endl;
    cout << "6. Clear the deque." << endl;
    cout << "7. Exit." << endl;
    cout << "-------------------------------------" << endl;
    cout << "Please enter your choice : ";
}
void lastOutLimitedQueueLoop(Queue *deque) {
    int choice;
    long long int dataGet;
    int data;
    do {
        system("clear");
        deque->showDeque();
        lastOutLimitedQueueMenu();
        cin >> choice;
        switch(choice) {
            case 1 :
                dataGet = deque->getFirst();
                if(dataGet == INT64_MIN) {
                    cout << "The deque is empty!" << endl;
                    cout << "Press any key to continue!" << endl;
                }else {
                    cout << "The first element : " << dataGet << endl;
                    cout << "Press any key to continue!" << endl;
                }
                getchar();
                getchar();
                break;
            case 2 :
                dataGet = deque->getLast();
                if(dataGet == INT64_MIN) {
                    cout << "The deque is empty!" << endl;
                    cout << "Press any key to continue!" << endl;
                }else {
                    cout << "The first element : " << dataGet << endl;
                    cout << "Press any key to continue!" << endl;
                }
                getchar();
                getchar();
                break;
            case 3 :
                cout << "Please enter the element you want to enter : ";
                cin >> data;
                deque->firstEnter(data);
                break;
            case 4 :
                cout << "Please enter the element you want to enter : ";
                cin >> data;
                deque->lastEnter(data);
                break;
            case 5 :
                deque->firstOut();
                break;
            case 6 :
                deque->clearDeque();
                break;
            case 7 :
                deque->clearVector();
                delete deque;
                exit(0);
            default :
                break;
        }
    }while(choice != 7);
}
void lastEnterLimitedQueueMenu() {
    cout << "-------------------------------------" << endl;
    cout << "1. Get the first element." << endl;
    cout << "2. Get the last element." << endl;
    cout << "3. First enter." << endl;
    cout << "4. First out." << endl;
    cout << "5. Last out." << endl;
    cout << "6. Clear the deque." << endl;
    cout << "7. Exit." << endl;
    cout << "-------------------------------------" << endl;
    cout << "Please enter your choice : ";
}
void lastEnterLimitedQueueLoop(Queue *deque) {
    int choice;
    long long int dataGet;
    int data;
    do {
        system("clear");
        deque->showDeque();
        lastEnterLimitedQueueMenu();
        cin >> choice;
        switch(choice) {
            case 1 :
                dataGet = deque->getFirst();
                if(dataGet == INT64_MIN) {
                    cout << "The deque is empty!" << endl;
                    cout << "Press any key to continue!" << endl;
                }else {
                    cout << "The first element : " << dataGet << endl;
                    cout << "Press any key to continue!" << endl;
                }
                getchar();
                getchar();
                break;
            case 2 :
                dataGet = deque->getLast();
                if(dataGet == INT64_MIN) {
                    cout << "The deque is empty!" << endl;
                    cout << "Press any key to continue!" << endl;
                }else {
                    cout << "The first element : " << dataGet << endl;
                    cout << "Press any key to continue!" << endl;
                }
                getchar();
                getchar();
                break;
            case 3 :
                cout << "Please enter the element you want to enter : ";
                cin >> data;
                deque->firstEnter(data);
                break;
            case 4 :
                deque->firstOut();
                break;
            case 5 :
                deque->lastOut();
                break;
            case 6 :
                deque->clearDeque();
                break;
            case 7 :
                deque->clearVector();
                delete deque;
                exit(0);
            default :
                break;
        }
    }while(choice != 7);
}