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) 文字編輯器設計:http://download.noi.cn/T/noi/noi2003A.pdf
程式實現參考:
http://hi.baidu.com/wuyijia/blog/item/7085fa004423cd86e850cdeb.html
(2) 維護隊列:http://download.noi.cn/T/noi/noi2005A.pdf
程式實現參考:
http://hi.baidu.com/zbwmqlw/blog/item/54cce1004e799c0c1d9583b7.html
5、 總結
由於塊狀鏈表的每個節點儲存的是一個數組,如果數組是靜態(的大小固定),則會浪費儲存空間;如是動態,則需要頻繁的申請或者釋放空間,嚴重降低系能。因此,當資料量非常龐大時,設計合理的數組空間維護策略顯得尤為重要。
6、 參考資料
(1) 論文《對塊狀鏈表的一點研究》
(2) 數組+鏈表=塊狀數組:http://starforever.blog.hexun.com/3184024_d.html
————————————————————————————————————-
更多關於資料結構和演算法的介紹,請查看:資料結構與演算法匯總
————————————————————————————————————-
原創文章,轉載請註明: 轉載自董的部落格
本文連結地址: http://dongxicheng.org/structure/blocklink/