1. 程式人生 > >陣列和連結串列的例項講解——以Facebook為例

陣列和連結串列的例項講解——以Facebook為例

陣列支援隨機訪問,而連結串列只能順序訪問。那在實際使用中什麼樣的場合下該使用陣列,或者連結串列呢?

  • 1、假設你要編寫一個記賬的應用程式。包含買雜貨、看電影和交會費。你每天都將記錄所有的支出,並在月底統計支出,算算當月花了多少錢。因此,你執行的插入操作很多,讀取操作很少,該使用陣列還是連結串列呢?
  • Ans:實際上每天都要新增支出項,月底讀取支出一次。陣列的讀取速度快,插入速度慢;而連結串列的讀取速度慢,插入速度快。由於執行的插入操作次數多於讀取操作,因此使用連結串列更為合適。另外,僅當你隨機讀取資料時,連結串列的訪問速度才慢。鑑於要讀取所有的資料,因此連結串列的速度並不慢。因此對於這個問題,使用連結串列很不錯。

下面是陣列和連結串列常見操作的複雜度:

操作 陣列 連結串列
插入 O(n) O(1)
讀取 O(1) O(n)
刪除 O(n) O(1)

Q1:每當你登入Facebook時,FB都會查詢你填寫的使用者名稱,如果找到則允許登入。因此FB需要執行大量的使用者名稱查詢操作。假設FB採用二分查詢演算法,而這種演算法要求能夠隨機訪問——立即獲取中間的使用者名稱。考慮到這一點,應使用陣列還是連結串列儲存使用者名稱?

Ans:隨機訪問顯然是陣列。

Q2:經常有使用者會在FB註冊。假設你已經決定使用陣列來儲存使用者名稱,在插入方面陣列有何缺點呢?具體滴說,在陣列中新增新使用者將出現什麼情況?

Ans:陣列的插入速度很慢,複雜度為O(n)。另外採用二分查詢必須之前就進行排序,因此每註冊一個使用者就需要重新排序,時間開銷極大。

Q3:實際上,FB儲存使用者資訊時使用的既不是陣列又不是連結串列。假設FB使用的是一種混合資料:連結串列陣列。在這個陣列中包含26個元素,每個元素都指向一個連結串列。例如,該陣列的第一個元素指向的連結串列包含以A開頭的使用者名稱,該陣列的第二個元素指向的連結串列包含以B開頭的使用者名稱……如下圖所示:

假設Adit B在FB註冊,而你需要將其加入前述資料結構中。因此,你訪問陣列的第一個元素,再訪問該元素指向的連結串列,並將Adit B新增到這個連結串列的結尾。現在假設你要查詢Zak H。因此你訪問第26個元素,再在它指向的連結串列中查詢Zak H。

請問,相比於陣列和連結串列,這種混合資料結構的插入和查詢速度是否更快?

Ans:查詢時,其速度比陣列慢,但比連結串列快;而插入時,與連結串列相當,比陣列快。因此,其查詢速度比陣列慢,但在各方面都不比連結串列慢。這種混合的連結串列陣列實際上是散列表的一個例子。

FB實際上使用的是什麼呢?很可能是十多個資料庫,他們基於眾多不同的資料結構:散列表、B數等。陣列和連結串列是這些高階資料結構的基石。


總結:

陣列的缺點就在於插入的時間複雜度較大,讀取速度較快,如果只插入不排序,會導致查詢的複雜度增大;而連結串列的缺點就在於不能隨機訪問,也就是讀取的速度較慢。但是插入和排序較快。連結串列陣列是它們兩者的結合,具有了兩者的優點,但也不是最理想的。

 

內容整理自Aditya Bhargava《演算法圖解》