1、 概述
在進行演算法設計時,我們常用的兩種線性資料結構是陣列和鍊錶。它們各有優缺點。陣列特點是元素在記憶體中緊挨著儲存,因而優點是定位快(o(1)),缺點是插入刪除慢(o(n));而鍊錶則不同,它通過指標將不同位置的元素鏈結起來,因而優缺點與陣列正好相反:定位慢(o(n)),插入刪除快(o(1))。本文介紹一種新的資料結構:塊狀鍊錶,它將陣列和鍊錶的優點結合來,各種操作的時間複雜度均為o(sqrt(n))。
2、 塊狀鍊錶的基本操作
塊狀鍊錶整合了陣列和鍊錶的優缺點,使得各種那個操作的時間複雜度均為o(sqrt(n))。 從整體上看,塊狀鍊錶是乙個鍊錶, 而在鍊錶的每個節點上,以陣列的形式儲存一組元素。具體如下:
基本操作:
(1)定位:先定位元素所在的鍊錶節點,然後再定位該元素在陣列中的位置。
(2)**:將某個鍊錶節點**成兩個節點。
(3)插入:首先定位要插入的位置,然後將所在節點**成兩個節點,並將資料放到第乙個節點的末尾。 如果要插入的是一大塊資料,首先要將資料切成多個block(每個block對應乙個塊狀鍊錶的乙個節點)並將這些block鏈起來,然後將它們插入那兩個節點之間。
(4)刪除:首先定位刪除元素的位置,然後按照陣列刪除元素的方法刪除該資料。如果刪除一大塊資料,首先要定位資料塊首元素和末元素所在的位置,然後分別將它們所在的節點**成兩個節點,最後刪除首元素和末元素之間的節點即可。
3、 關鍵點和複雜度分析
該演算法的核心是確定鍊錶長度和每個節點的陣列長度,以及怎麼保證這個長度值?設塊狀鍊錶中元素總個數為x,鍊錶長度為n,每個節點中資料長度為m,則當m=n=sqrt(x)時,可保證m和n同時最小,此時各種操作的時間複雜度最低。在實際應用時,需維持塊狀鍊錶的每個節點大小在[sqrt(n)/2, 2*sqrt(n)],否則,塊狀鍊錶會退化。維護方法是,適當的時候,對節點進行合併與**(維護本身不會使複雜度增加)。
4、 應用
(1) 文字編輯器設計:
程式實現參考:
(2) 維護佇列:
程式實現參考:
5、 總結
由於塊狀鍊錶的每個節點儲存的是乙個陣列,如果陣列是靜態的(的大小固定),則會浪費儲存空間;如是動態的,則需要頻繁的申請或者釋放空間,嚴重降低系能。因此,當資料量非常龐大時,設計合理的陣列空間維護策略顯得尤為重要。
6、 參考資料
(1) **《對塊狀鍊錶的一點研究》
(2) 陣列+鍊錶=塊狀陣列:
————————————————————————————————————-
更多關於資料結構和演算法的介紹,請檢視:資料結構與演算法彙總
————————————————————————————————————-
資料結構 表之煉表
頭插法建立 尾插法建立 顯示 銷毀 include include using namespace std typedef int elemtype typedef struct lnode linklist void createlinklistf linklist l,elemtype a,in...
資料結構之鍊錶
頭結點 第乙個有效結點之前的那個結點 頭結點並不存有效資料 加頭結點的目的主要是為了方便對鍊錶的操作 頭指標 指向頭結點的指標變數 尾指標 指向尾節點的指標變數 如果希望通過乙個函式對鍊錶進行處理,只需要乙個引數 頭指標 首先要定義乙個單鏈表儲存結構 然後建立乙個空表,即初始化,我寫的這個提前設定好...
資料結構之鍊錶
鍊錶是一種基本的資料結構型別,它由乙個個結點組成。每乙個結點包括乙個資料的儲存和乙個指向下乙個結點的引用。在這個定義中,結點是乙個可能含有任意型別資料的抽象實體,它所包含的指向結點的應用顯示了它在構造鍊錶之中的作用。和遞迴程式一樣,遞迴資料結構的概念一開始也令人費解,但其實它的簡潔性賦予了它巨大的價...