1. 程式人生 > >演算法快學筆記(二):陣列與連結串列

演算法快學筆記(二):陣列與連結串列

1. 說明

當程式需要將資料儲存到記憶體時,計算機會給你一個儲存地址。需要存
儲多項資料時,有兩種基本方式——陣列和連結串列。但它們並非都適用於所有的情形,因此知道它們的特性很重要。本文將對陣列與連結串列的原理與優缺點進行總結。

2. 陣列

使用陣列儲存多個元素的時候,陣列中元素的地址時刻都是挨在一起的,為了便於理解,以看電影為例進行說明。

你和你小夥伴的關係都非常的好,如果一起看電影必須要座位要挨在一起,你先和兩個小夥伴去看電影,到了電影院只坐有連續三個空位的地方(陣列初始化)。找到地方就坐後又來了一位朋友,但原來坐的地方沒有空位置,這時只能重新找一個可坐下所有人的地方(陣列插入新元素

)。如果又來了一位朋友,而當前坐的地方也沒有空位,你們就得再次轉移!好不容易安穩的看了會電影,有個小夥伴又要離開,為了讓大家都緊挨著,有一部分小夥伴就需要挪動下座位(陣列刪除元素)。

真是太麻煩了。同樣,在陣列中新增/刪除元素也很麻煩。因此陣列新增/刪除元素的速度都會很慢。

對於新增元素的一種解決之道是“預留座位”:即便你們現在只有3個小夥伴,也請計算機提供10個位置,以防臨時有朋友來的情況。這樣,只要小夥伴不超過10個,就無需轉移。
該方案存在兩個缺點。

  • 你額外請求的位置可能根本用不上,這將浪費記憶體。你沒有使用,別人也用不了。
  • 待辦事項超過10個後,你還得轉移。

3. 連結串列

連結串列的每個元素都儲存了下一個元素的地址,從而使一系列隨機的記憶體地址串在一起,因此連結串列中的元素可儲存在記憶體的任何地方,當新增/刪除元素時其他的元素都不需要移動。同樣以看電影為例對連結串列進行說明。

假設你與10位朋友去看一部很火的電影。你們11人想坐在一起,但看電影的人較多,沒有11個在一起的座位,如果是陣列的解決方式,這個電影就看不了了,因為實在沒有這麼多空的位置是在一起的。連結串列的解決方式是“既然這樣,我們分開來坐,但是為大家之間還可能會聯絡,因此每個人都依次記得下一個人的座位號,例如A記得B的座位號是008,B記得C的座位號是102…”,因此,只要有足夠的記憶體空間,就能為連結串列分配記憶體

4. 陣列與連結串列的查詢

從看電影的例子可以看出,使用連結串列的方式,解決入場觀看(初始化),以及中途人員變動(新增/刪除)是一個比較好的方案,但是如果用來找你的小夥伴了?考慮以下兩種操作

4.1 全部查詢

  1. 陣列方式:由於所有小夥伴都做在一起,只要找到第一個,其他的就都能找到。
  2. 連結串列方式:雖然小夥伴都是分散做的,但是由於每個小夥伴都知道下一個小夥伴的座位號,因此要找全部小夥伴也比較方便

4.2 隨機查詢

假設10個小夥伴的入場看電影的時候,是按照年齡從小到大的順序入場的,你突然要找年齡最大的那個小夥伴。

  1. 陣列方式:由於所有小夥伴都做在一起,找到第一個人後,他的座位號+10就是年齡最大的那個小夥伴。
  2. 連結串列方式:由於小夥伴都是分散坐的,所以你只能從第一個人問第二個人的座位號,到第二個人那邊後,問他第三個人的座位號,以此類推。

通過上面的例子可以看出,在隨機讀取的場景:

  1. 需要隨機地讀取元素時,陣列的效率很高,因為可迅速找到陣列的任何元素。
  2. 在連結串列中元素並非靠在一起的,你無法迅速計算出第i個元素的記憶體地址,而必須先訪問第一個元素以獲取第二個元素的地址,再訪問第二個元素以獲取第三個元素的地址,以此類推,直到訪問第i個元素。

5. 總結

  • 需要儲存多個元素時,可使用陣列或連結串列。
  • 陣列的元素都在一起。
  • 連結串列的元素是分開的,其中每個元素都儲存了下一個元素的地址。
  • 陣列的隨機讀取速度很快。
  • 連結串列的插入和刪除速度很快。
  • 在同一個陣列中,所有元素的型別都必須相同(都為int、 double等)。