天天看點

資料結構的存儲方式

作者:程式員的交流電

說到資料結構,我們可能會想到各種各樣的資料結構:如果棧,隊列,樹,圖,散清單,再進階一些,可能學過堆,優先隊列,線段樹,并查集和AVL樹,紅黑樹等。上面說的資料結構,基本上都可以使用數組或連結清單兩種存儲方式來實作的。

資料結構的存儲方式隻有兩種:數組(順序存儲結構)和連結清單(鍊式存儲結構)。

數組和連結清單是資料結構存儲資料的方式,而棧堆樹圖等資料結構是在使用數組和連結清單存儲資料的基礎上,對資料相關操作進行規則的限制和定義,究其源頭,都是在數組或者連結清單上進行特殊操作,API不同而已。

比如說“隊列”,“棧”,隊列限制資料先進先出,棧限制資料先進後出,這兩種資料結構既可以使用連結清單也可以使用數組來實作,對應實作不同的api而已,使用數組,需要處理資料移動和擴容縮容的問題;使用連結清單需要更多的記憶體空間來存儲指向節點的指針。

資料結構的存儲方式

棧和隊列

“圖”主要有兩種實作方式,鄰接表和鄰接矩陣,其中鄰接表是連結清單實作的,鄰接矩陣是二維數組實作的。鄰接矩陣判斷連通性更适合,可以進行矩陣運算解決一些問題,但如果資料稀疏的話,就好浪費記憶體空間了。鄰接表比較節省空間,但是操作效率上肯定比不上鄰接矩陣。

資料結構的存儲方式

“散清單”是通過散列函數把鍵值對映射到一個大的數組中,可以使用拉鍊法解決資料沖突,拉鍊法底層使用的是連結清單的特性,java中的HashMap就是這樣實作的,即使用了數組,也使用連結清單解決沖突。

資料結構的存儲方式

散清單

“樹”, 可以⽤數組實作,比如“堆”,因為「堆」是⼀個完全⼆叉樹,⽤數組存 儲不需要節點指針,操作也比較簡單;⽤連結清單實作就是很常⻅的那種 「樹」,因為不⼀定是完全⼆叉樹,是以不适合⽤數組存儲。為此,在這種 連結清單「樹」結構之上,⼜衍⽣出各種巧妙的設計,⽐如⼆叉搜尋樹、AVL 樹、紅⿊樹、區間樹、B 樹等等,以應對不同的問題。

資料結構的存儲方式

資料結構種類有很多,甚至你可以定義自己的資料結構,但是底層的存儲方式無非就是數組或者連結清單。

“數組” 底層連續存儲,可以随機通路,能夠通過索引快速找到對應元素,是以當索引具有業務含義的時候,根據索引能夠實作O(1)時間複雜度的查詢。但正因為連續存儲,記憶體空間必須⼀次性配置設定夠,所 以說數組如果要擴容,需要重新配置設定⼀塊更⼤的空間,再把資料全部複制過 去,時間複雜度 O(N);⽽且你如果想在數組中間進⾏插⼊和删除,每次必 須搬移後⾯的所有資料以保持連續,時間複雜度 O(N)。

“連結清單” 每存入一個元素,需要申請記憶體空間,是以連結清單是不連續的,是靠指針指向下⼀個元素的位置,是以不存在擴容問題;如果知道某⼀元素的前驅和後驅,操作指針即可删除該元素或 者插⼊新元素,時間複雜度 O(1)。但是正因為存儲空間不連續,你⽆法根 據⼀個索引算出對應元素的位址,是以不能随機通路,查詢資料需要周遊通路,時間複雜度為O(n);⽽且由于每個元素必 須存儲指向前後元素位置的指針,會消耗相對更多的儲存空間。

基本上現在的大廠面試,算法是肯定要考的,每次想沖擊大廠,想到自己的算法都會覺得很無奈。算法的學習是持之以恒的,不是一蹴而就得,是以打算最近要持續學習資料結構和算法。這裡我主要閱讀了labuladong的算法小抄,覺得寫的非常好,大家可以去關注一下,在這裡說明一下,歸納總結一下自己學習心得。

繼續閱讀