佇列是一種特殊的線性表,它的特殊之處在於它必須在佇列的頭部進行刪除元素,在佇列尾部插入元素。我們把佇列的頭部稱為對頭(front),佇列尾部叫做隊尾(rear)。進行刪除元素位置叫隊頭(front),進行插入元素的位置叫在隊尾(rear)。
佇列的儲存的資料稱為佇列元素,因為只能在對頭進行刪除的操作,隊尾進行插入,先插入的先出隊,所以我們可以稱隊列為一種先進先出(fifo:first in first out )的資料結構。
建立順序儲存結構,我們必須動態申請或靜態地分配一塊儲存位置,設定兩個指標來進行管理,分別稱為對頭head、隊尾tail,當隊頭與隊尾相等時
(head==tail)我們稱為隊空。隊頭指標指向佇列第乙個插入的元素,tail指標指向佇列最後乙個插入元素的下乙個位置,當佇列中插入乙個元素時,tail+1;刪除
乙個元素時,head+1。
我們來看乙個圖:
在圖中我們可以到,圖1.3,當隊頭元素被刪除後,會留下一塊儲存區域,它並不會再次被使用,所以會造成記憶體的浪費。圖1.4中反應了這樣乙個現象,當佇列所
申請的記憶體最後一塊儲存空間被占有時,當想要再插入乙個新的元素時,就會產生問題,這種現象稱為「假溢位」。
為了避免上述的問題,因此出現了乙個新的概念:迴圈佇列。
迴圈佇列,我們假想成乙個迴圈模型,如下圖所示:
當front==rear時表示隊空;當迴圈出佇列、入佇列的過程中會發生一種情況,隊尾在元素一的位置,隊頭在元素二的位置,那麼頭尾指標也恰好指向同乙個位置,這時我們稱為隊滿,是不是也是front==rear?
這裡我用陣列方式來實現迴圈佇列:
typedef int quetype;
typedef int status;
#define capacity 4
*採用資料儲存元素,陣列型別為:int
*實現佇列初始化、出佇列、入佇列、統計佇列總數、迴圈遍歷佇列元素等功能。
*/typedef structmyqueue;
//佇列初始化
int initqueue(myqueue *q)
//判斷佇列是否為空
//為空返回0,否則為-1
int queueempity(myqueue *q)
return -1 ;
}//判斷佇列是否已滿
//為空返回0,否則為-1
int queuefull(myqueue *q)
return -1 ;
}//入隊
status enqueueele(myqueue *q , quetype ele)else
return 0;
}//出隊
int dequeueele( myqueue *q,quetype *ele)else
return 0;
}//獲取第一元素
int gethead(myqueue *q ,quetype *ele)
//統計佇列元素個數
int getqueuesize(myqueue *q)
//遍歷元素
void showqueuelist(myqueue *q)
}
測試:
int main(void)
結果:
佇列的鏈式儲存的兩種定義方式
佇列的鏈式儲存的定義結點 初始化 判斷空 入隊 出隊 讀取隊頭元素 求佇列長度操作 方法一 這種鏈佇列有頭指標,上圖分別為鏈隊列為空 非空 只有乙個元素的時候的情況,如下 佇列的鏈式儲存和操作的實現 include include includetypedef int datatype typede...
redis實現延時佇列的兩種方式
專案中的流程監控,有幾種節點,需要監控每乙個節點是否超時。按傳統的做法,肯定是通過定時任務,去掃瞄然後判斷,但是定時任務有缺點 1,資料量大會慢 2,時間不好控制,太短,怕一次處理不完,太長狀態就會有延遲。所以就想到用延遲佇列的方式去實現。1,開啟過期key監聽 在redis的配置裡把這個注釋去掉 ...
陣列模擬佇列的兩種方式
基本陣列模擬佇列 陣列模擬佇列 arrayqueue類 class arrayqueue1 判斷佇列已滿,當佇列尾指向陣列的頭時代表佇列已滿 public boolean isfull 判斷佇列是否為空,佇列的頭和尾指向統一個地方時,代表隊列為空 public boolean isempty 在佇列...