資料結構 ArrayDeque 雙向陣列佇列

2022-08-24 13:30:23 字數 2622 閱讀 9709

簡介優先順序佇列只支援從一段取資料,內部結構是陣列,但是必須符合二叉堆,每次取資料都會伴隨上移下移,如果我們元素不不需要排序,有沒有更好的佇列呢?arraydeque 就能滿足這個需要,並且它可以在兩端方資料和取資料,內部也是用陣列實現。

arraydeque 類

public class arraydequeextends abstractcollectionimplements deque, cloneable, serializable
arraydeque 繼承abstractcollection抽象類,並且實現deque介面

arraydeque 屬性

// 元素陣列,長度為2的冪

transient object elements;

// 頭指標

transient int head;

// 尾指標

transient int tail;

// 最小長度

private static final int min_initial_capacity = 8;

arraydeque 建構函式
public arraydeque() 

public arraydeque(int numelements)

public arraydeque(collection extends e> c)

private void allocateelements(int numelements)

private static int calculatesize(int numelements)

// 返回的是初始值

return initialcapacity;

}

是否還記得hashmap中初始長度求最小2的冪?calculatesize中那一長串也是這個作用。可以看出初始陣列長度預設16,最小不能小於8,如果傳2的n次冪,最終長度是2的n+1次冪,hashmap中為了解決這個問題先減1在位移

arraydeque 新增

public void addfirst(e e)
很多人在看head = (head - 1) & (elements.length - 1)時會比較暈,這裡細說一下,elements.length一定是2的n次冪不用多說,轉換為二進位制就是n+1位為1,其他位為0,那麼elements.length - 1呢?從右往左n位都是1。舉例elements.length為16,第一次新增時head=0 head - 1 = -1 (1的反碼再取補碼)轉為二進位制32個1,32個1和15取位於結果就是15;第二次新增時head=15 head - 1 = 14 轉為二進位制 1110,1110 & 1111結果為1110 (14),實際上head = (head - 1) & (elements.length - 1)就是最後一位開始遞減

public void addlast(e e)
tail = (tail + 1) & (elements.length - 1)也是同樣的道理,實際上就是從第一位開始累加,而(tail = (tail + 1) & (elements.length - 1)) == head,就是前後指標是否相同了。這裡為什麼不用tail + 1?這裡是考慮head值為0的情況,設elements.length = 16,當head為0,tail當前值為15時實際上陣列這時已經滿了,但是怎麼判斷陣列滿了呢?tail + 1 = 16, elements.length - 1 = 15, head = 0,那麼10000 & 1111 = 00000000 == head,這裡是一處非常巧妙的做法,簡單一行做了很多事 將tail+1的同時還能判斷陣列有沒有滿,與運算又能提高程式效率。需要注意的是,這裡是把元素放在tail位置之後再把tail+1的,也就是說tail下標位置是沒有值的,也就是含頭不含尾

arraydeque 擴容

private void doublecapacity()
arraydeque 擴容是原陣列長度擴大一倍

arraydeque 刪除

// 將佇列首部的元素取出並移除

public e removefirst()

// 將佇列尾部的元素取出並移除

public e removelast()

arraydeque 出隊
// 將佇列首部的元素取出並移除

public e pollfirst()

// 將佇列尾部元素取出並移除

public e polllast()

removefirst,removelast 這兩個方法也是移除並返回元素,和pollfirst不同的是該介面會判斷返回的值是否為null,如果為null,就丟擲異常。也就是說,該方法不允許要移除的元素為null。還有兩個方法,peekfirst,peeklast也是返回頭元素或尾元素,只是不移除元素。

資料結構 雙鏈表

typedef struct nodenode 雙鏈表的根節點的bwd指標指向雙鏈表的最後乙個節點,fwd指標指向雙鏈表的第乙個節點,雙鏈表的value欄位為空 以下程式是將乙個值插入到乙個有序的雙鏈表中,如果鍊錶中已經有和該值相同的節點則不插入 include include typedef st...

資料結構 雙鏈表

目標 掌握雙鏈表的資料結構 來看看什麼是雙鏈表吧 雙鏈表與單鏈表的區別,單鏈表是單項的 而雙鏈表是有左右的 題目acwing 827 實現乙個雙鏈表,雙鏈表初始為空,支援5種操作 1 在最左側插入乙個數 2 在最右側插入乙個數 3 將第k個插入的數刪除 4 在第k個插入的數左側插入乙個數 5 在第k...

資料結構 雙鏈表

單鏈表結點中只有乙個只指向後繼的指標,使得單鏈表只能從頭結點開始一次順序的先後遍歷。要訪問某個結點的前驅結點 插入刪除操作時 只能從頭開始遍歷,訪問後繼節點的時間複雜度為o 1 訪問前驅結點的時間複雜度為o n 為了克服單鏈表的上述缺點,引入了雙鏈表,雙鏈表結點中有兩個指標prior 和 next,...