1. 程式人生 > >C++模板實現佇列(2)

C++模板實現佇列(2)

迴圈佇列中新增和刪除元素時並不像鏈式佇列那樣使用動態記憶體分配,一般採用固定的佇列長度,一次分配一片記憶體用於儲存資料,等到佇列使用完畢後釋放掉即可。記憶體使用效率比鏈式佇列高,也比較容易實現。佇列的資料定義如下:

    unsigned int size;//儲存總的佇列大小,最多可以儲存size-1個數據
    int head;//記錄隊頭的下標
    int rear;//記錄隊尾的下標
    T* data_buff;//資料儲存緩衝區

佇列為空時:

rear=head;

這裡寫圖片描述
元素入隊時,向前移動rear一次,但是rear所指的那個地方並不儲存資料,迴圈佇列總會空出一個位置不儲存元素:

data_buff[rear] = data;
rear = (rear + 1) % size;

這裡寫圖片描述
上圖中,表示向佇列中依次新增元素‘A’、‘B’。
出隊時,隊頭head向前移動一次;

data_buff[head] = 0;
head++;

這裡寫圖片描述
上圖中將隊頭的元素‘A’出隊。
判斷佇列已滿時,採用的方法與鏈式佇列不同,判斷的條件變為:

head ==(rear + 1) % size 

這裡寫圖片描述
佇列已滿的情況。
接下來使用C++模板程式設計實現一個迴圈佇列類。

template<typename T>
class RQueue
{
private:
    unsigned
int size; int head; int rear; T* data_buff; public: RQueue() :size(10), head(0), rear(0) { data_buff = new T[size]; } RQueue(int s) :size(s), head(0), rear(0) { data_buff = new T[size]; } ~RQueue() { delete [] data_buff; } void
enqueue(T data) { if (isfull()) { cout << "Error: This RQueue is full" << endl; cout << "File Path =" << __FILE__ << endl; cout << "Function Name =" << __FUNCTION__ << endl; cout << "Line =" << __LINE__ << endl; throw bad_exception(); } data_buff[rear] = data; rear = (rear + 1) % size; } void dequeue() { if (isempty()) { cout << "Error: This RQueue is empty" << endl; cout << "File Path =" << __FILE__ << endl; cout << "Function Name =" << __FUNCTION__ << endl; cout << "Line =" << __LINE__ << endl; throw bad_exception(); } data_buff[head] = 0; head++; } T getHeadElem() { if (isempty()) { cout << "Error: This RQueue is empty" << endl; cout << "File Path =" << __FILE__ << endl; cout << "Function Name =" << __FUNCTION__ << endl; cout << "Line =" << __LINE__ << endl; throw bad_exception(); } return data_buff[head]; } unsigned int elem_available() { int temp; if (rear > head) temp = rear - head; else temp = size - head + rear; return temp; } bool isempty() { return head == rear ? true : false; } bool isfull() { return head == (rear + 1) % size ? true : false; } void show() { for (int i = 0; i < elem_available();) { cout << data_buff[(i+head)%size]<<" "; i = (i + 1) % size; } cout << endl; } };

老套路,測試一下:

int main()
{
    RQueue<float> rq;
    for (int i = 0; i < 9; i++)//將9個元素入隊
        rq.enqueue(i);
    rq.show();
    for (int i = 0; i < 6; i++)//出隊6個元素
    {
        cout << rq.getHeadElem() << " ";
        rq.dequeue();
    }
    cout << endl;
    for (int i = 0; i < 5; i++)//入隊5個元素
        rq.enqueue(i);
    rq.show();
    system("pause");
    return 0;
}

這裡寫圖片描述