佇列又是一種特殊的線性表。特殊之處在於:
想要移除線性表中的元素,必須從首元素開始移除;
想要往線性表中插入元素,必須在尾部進行插入
與棧遵循的先入後出原則不同,它遵循的是先入先出的原則。拿到乙個佇列,我們可以對它進行入隊(隊尾插入)和出隊(隊首刪除)操作。
假如我想要使用佇列,我肯定要先拿到乙個佇列。如果採用鍊錶結構,利用鍊錶的動態增長特性,我們倒是可以不用考慮佇列的容量問題,但是因為要動態建立和刪除節點,效率較低。用鍊錶實現佇列思想比較容易,這裡我們就不用鍊錶來實現了。
下面我們用順序儲存方式來實現佇列。使用順序儲存結構,我們就要在建立佇列的時候就規定佇列的容量,比如我們可以用下面的**建立乙個容量為10的整型佇列
拿到queue這個佇列物件,我們便可以讓資料入隊,出隊了,queue
*queue
=new
queue
(10);
既然我們想如此操作佇列,那麼便可以如此定義佇列這個類了:queue
->adddatatoqueue(1);
queue
->adddatatoqueue(2);
queue
->adddatatoqueue(3);
queue
->adddatatoqueue(4);//此時佇列中有1、2、3、4
queue
->deletedatafromqueue();
queue
->deletedatafromqueue();//此時佇列中有3、4
按照一般思維,開始的時候_front和_rear都在陣列的0位置處,入佇列則把_rear加1向後移動一位,出佇列則把_front加1,向後移動一位。但是這種方法是有問題的,我在下面畫**釋:templateclass queue
;
所以我們一般採用迴圈佇列的形式,在上圖中,當9入佇列後,_rear應該變成4,我們把4對4取餘得到0,設定_rear=0,這時隊滿了,_front = _rear又都等於0(如下圖),我們發現這與隊空時的情形是一樣的。
這樣就沒法區分隊滿和隊空了。所以,一般的方法是當佇列中裝了(總容量-1)個資料時就認為佇列滿了,這樣就可以用(_rear + 1) % _capacity == _front作為隊滿的判斷條件。
邏輯上的講完了,下面給出乙個簡單的**實現
template
class queue
~queue()
bool adddatatoqueue(datatype data)//入隊操作
datatype deletedatafromqueue()//出隊操作private:
int _capacity;
int _front;
int _rear;
datatype* _datas;
};
旭說資料結構之樹的簡介
線性表是一對一的資料結構。樹是一對多的資料結構。樹的定義是 有n n 0 個結點,樹的定義中允許結點個數為0的情形,結點之間有一定的關係,什麼關係呢,1.當n 0 時,我們稱這個樹為空樹 2.當 n 0 時,有乙個特定的結點被稱之為根節點 root 然後其餘結點都連在根結點的下面並進行延伸,與根節點...
旭說資料結構之棧的小題目
1.定義棧的資料結構,要求新增乙個min 函式,能夠得到棧的最小元素。要求函式min push 及pop 函式的時間複雜度都是o 1 思考1 如果說我們給棧這個類新增乙個成員變數min,用來記錄棧中的最小值。1.假設第一次push進入元素1時,設定min 1 2.再次想讓2進棧時,先把2和min進行...
旭說資料結構之鍊錶補充(雙向鍊錶)
上文已經介紹了鍊錶中的單鏈表,這裡我們再敘述一下雙向鍊錶 1.雙向鍊錶 對比單鏈表,雙向鍊錶能夠直接找到節點的前驅,也就能從任意乙個節點到達鍊錶的頭結點和尾節點。如下圖所示 下面我們還是從使用的角度出發來定義雙向鍊錶的介面。我想使用乙個雙向鍊錶,那我就new乙個來用。然後我就往裡插入元素。之後我又想...