1.
佇列的定義
佇列是只允許在一端進行插入操作,而在另一端進行刪除操作的線性表。佇列是一種先進先出的線性表。允許插入的一端稱為隊尾,允許刪除的一端稱為隊頭。
2. 佇列的抽象資料型別
關於佇列的操作有:
(1)
initqueue(*q):初始化操作,建立乙個共佇列q
(2)
queueempty(*q):判斷佇列是否為空
(3)
enqueue(*q,e):插入新元素到佇列中並成為隊尾元素
(4)
queuelength(q):返回佇列的個數
(5)
gethead(q,*e):
獲取佇列隊頭元素
(6)
dequeue(*q,*e):刪除佇列中的隊頭元素
(7)
clearqueue(*q):清空佇列
(8)
destroyqueue(*q):若佇列存在,則銷毀它
3. 佇列順序儲存的不足
我們假設乙個佇列有
n個元素,則順序儲存的佇列需建立乙個大於n的陣列,並把佇列的所有元素儲存在陣列的前n個單元,陣列下標為0的一端即為隊頭。所謂的入佇列操作,就是在隊尾追加乙個元素,不需要移動任何元素,因此時間複雜度為o(1)。佇列元素的出隊是在隊頭,即下標為0 的位置,那也就意味著佇列中的所有都得向前移動,以保證隊頭不為空,此時時間複雜度為o(n).當陣列末尾元素已經占用,再向後加,就會產生陣列越界的錯誤,但實際上佇列在前面的地方還是空閒的,這種現象較「假溢位」。
4. 迴圈佇列定義
解決假溢位的辦法是後面的滿了,就再從頭開始,也就是頭尾相接的迴圈。我們把佇列的這種頭尾相接的順序儲存結構稱為迴圈佇列。
5. 引入迴圈佇列的原因
為了避免陣列插入和刪除時需要移動資料,於是引入例迴圈佇列,使得隊頭和隊尾可以在陣列中迴圈變化。這解決了移動資料的時間損耗,使得本來插入和刪除是
o(n)的時間複雜度變成了o(1)。
6. 迴圈佇列中的一些操作
引入兩個指標,
front指標指向隊頭元素,rear指標指向隊尾元素的下乙個位置,當front等於rear時,此佇列是乙個空佇列。
佇列的最大尺寸為
queuesize,佇列滿的條件是 (
rear+1)%queuesize == front。通用的計算佇列長度的公式為:(rear-front+queuesize)%queuesize
7. 迴圈佇列的弊端
單是順序儲存,演算法的時間效能是不高的,但迴圈佇列又面臨著陣列可能會溢位的問題,所以我們需要研究一下不用擔心佇列長度的鏈式儲存結構。
8. 佇列的鏈式儲存結構定義
佇列的鏈式儲存結構,就是線性表的單鏈表,不過它只能尾進頭出,簡稱為鏈佇列。為了方便操作,我們將隊頭指標指向鏈佇列的頭結點,而隊尾指標指向終端結點。
9. 佇列的鏈式儲存結構操作
(1)
入隊操作:入隊操作時,就是在鏈尾部插入結點
(2)
出隊操作:出隊操作時,就是頭結點的後繼結點出隊,將頭結點的後繼改為它後面的結點,若煉表除頭結點外只剩乙個元素時,則需要將
rear指向頭結點。
10.
迴圈佇列和鏈佇列的比較
從時間上,它們的基本操作都是常數時間
o(1),不過迴圈佇列是事先申請好空間,使用期間不釋放;對於鏈佇列來說,每次申請和釋放結點也會存在一些時間開銷,如果入隊出隊頻繁,則兩者還是有細微差異。隊於空間上來說,迴圈佇列必須有乙個固定的長度,所以就有了儲存元素個數和空間的浪費。鏈佇列則不存在這個問題,儘管它需要乙個指標域,會產生一些空間上的開銷,但可以接受。所以在空間上鏈佇列更加靈活。
在可以確定佇列最大值的情況下,建議用迴圈佇列,如果無法預估佇列的長度時,則用鏈佇列。
AsynckTask幾點需要注意的幾個地方
問題一 asynctask是多執行緒麼?是的 問題二 asynctask與handler相比,誰更輕量級?通過原始碼可以發現asynctask實際上就是乙個執行緒池,而網上的說法是asynctask比handler更輕量級,顯然這是不準確的說法,只能這樣說,ansytask在 上比handler要輕...
關於Map Set list集合需要注意的地方
一 非空判斷 如果object為null,則設定為defaultvalue objectutils.defaultifnull object,defaultvalue 判斷集合是否為null listlist new arraylist system.out.println list.isempty...
資料結構預習筆記(棧和佇列)
1.棧的定義 棧是限制僅在表的一端進行插入和刪除運算的線性表又稱為 後進先出表 lifo表 插入 刪除端稱為棧頂,另一端稱棧底 表中無元素稱空棧。2 棧的邏輯結構和儲存表示 棧的邏輯結構和線性表相同。棧的抽象資料型別有兩種典型的儲存表示 基於陣列的儲存表示和基於鍊錶的儲存表示。1 基於陣列的儲存表示...