線性表之順序表與單鏈表的區別及優缺點

這裏比較的是基於C語言實現的順序表與單鏈表,與其他語言的實現可能會有差異,但我相信語言是相通的,它們的實現機制應該也差不多。
1、What
什麼是順序表和單鏈表
①順序表:
順序表是在計算機內存中以數組的形式保存的線性表,是指用一組地址連續的存儲單元依次存儲數據元素的線性結構。只要確定了起始位置,表中任一元素的地址都通過下列公式得到:LOC(ai)=LOC(a1)+(i-1)*L  1≤i≤n 其中,L是元素佔用存儲單元的長度。

這裏寫圖片描述

②單鏈表:
單鏈表是一種鏈式存取的數據結構,用一組地址任意的存儲單元存放線性表中的數據元素。它的數據是以結點(類型一般爲結構體)來表示的,每個結點的構成:數據(類型爲要存儲的數據的類型) + 指針(結構體指針),數據就是鏈表裏具體要存儲的東西,指針就是用來把每個節點都連接起來,使它們形成一個鏈狀。

結點:
這裏寫圖片描述

鏈表:

這裏寫圖片描述

這裏寫圖片描述

2、Compare
二者的優缺點比較

①空間上的比較(Space)
a. 空間的開闢:
順序表的實現一般是實現連續開闢一段空間,然後在進行數據的增刪查改(靜態順序表),所以順序表一般是固定空間大小的;而單鏈表則是一次只開闢一個結點的空間,用來存儲當前要保存的數據及指向下一個結點或NULL的指針,所以單鏈表的空間大小時動態變化的。(當然,順序表也可以在初始化時利用malloc函數來開闢一塊空間,每當空間不夠用時,再用realloc來把當前空間擴容成2倍,從而也能實現空間的動態變化(動態順序表))。

b. 空間的使用:
當我們不知道要存儲多少數據時,用順序表來開闢的空間如果太大,就會造成一定程度上的浪費,而用單鏈表是實現時,因爲是每需要存儲一個數據時,纔開闢一個空間,雖然有非數據項的指針佔空間,但相比順序表來說,浪費不是那麼明顯;反之,當我們知道存儲的數據的數量時,用順序表來開闢對應的空間大小,來存儲數據,因爲順序表中每個元素的存儲密度爲 1,就完全不會有浪費的空間,而用單鏈表,因爲每個結點都會有非數據項得指針,那麼就會造成空間的浪費。再者,編譯器會爲每個程序從內存上分配一段空間,給該程序使用。然而我們每次開闢空間時都是在隨機的位置開闢的,那麼使用單鏈表,就會多次的在程序分配到的這塊空間上開闢空間,因爲每次都是開闢的位置都是隨機的,那麼可能會把這塊空間搞得七零八碎,出現很多小的一般使用不到的碎片空間,這樣很大程度上造成了空間的浪費,而使用順序表的話,不會經常開闢空間,這樣就減少了碎片空間的出現,那麼就一定程度上節省了空間。
這裏寫圖片描述

這裏寫圖片描述

c. 對CPU高速緩存的影響:
因爲順序表的空間一般是連續開闢的,而且一次會開闢存儲多個元素的空間,所以在使用順序表時,可以一次把多個數據寫入高速緩存,再寫入主存,順序表的CPU高速緩存效率更高,且CPU流水線也不會總是被打斷;而單鏈表是每需要存儲一個數據纔開闢一次空間,所以每個數據存儲時都要單獨的寫入高速緩存區,再寫入主存,這樣就造成了,單鏈表CPU高速緩存效率低,且CPU流水線會經常被打斷。

從這兒看,貌似順序表要更好一些,真是如此嗎?繼續看下去。

②時間上的比較(Time)

a. 訪問隨機元素的時間複雜度:
因爲順序表的結構就像是數組一樣,可以用下標來訪問它的元素,所以它的元素是支持隨機訪問的;相比之下,單鏈表的數據是鏈式存儲的,它的元素是不支持隨機訪問的,想要知道某個元素,只能從頭結點開始遍歷整個鏈表,知道找到了該元素爲止。因此順序表訪問隨機元素的時間複雜度是O(1),而單鏈表訪問隨機元素的平均時間複雜度是O(n)。

b. 隨機位置插入、刪除元素的時間複雜度:
因爲順序表的元素是連續存儲的,因此要在特定位置插入、刪除元素需要把它之後的元素全部後移或前移一個元素的位置,時間開銷很大;而單鏈表在插入或刪除元素時,只需要改變它的前驅元素及插入或刪除元素的指向即可。因此,順序表在插入隨機位置插入、刪除元素的平均時間複雜度是O(n),單鏈表在插入隨機位置插入、刪除元素的時間複雜度是O(1)。

一般來說線性表(順序表和單鏈表都屬於線性表)的插入刪除操作會被執行的頻繁一些,因此,使用單鏈表的頻率較大。

3、Summary

綜合上述所言,順序表和單鏈表各有各的優缺點,使用哪一種會好一些要結合具體的問題而言,不能一概而論。
比如:
在查詢操作使用的比較頻繁時,使用順序表會好一些;在插入、刪除操作使用的比較頻繁時,使用單鏈表會好一些。

PS:使用順序表和鏈表都必須滿足每個元素佔有相同大小的內存空間,並且這個大小是固定的

發佈了68 篇原創文章 · 獲贊 80 · 訪問量 19萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章