學習 JS 資料結構(2):連結串列

Damonare發表於2016-11-23

上一篇部落格《學習 JS 資料結構(1):棧和佇列》說了棧和佇列在JS中的實現,我們運用JS提供的API很容易的實現了棧和佇列,但這種資料結構有一個很明顯的缺點,因為陣列大小是固定的,所以我們在移除或是新增一項資料的時候成本很高,基本都需要把資料重排一次。(JS的Array類方法雖然很方便但背後的原理同樣是這樣的)

相比陣列我們今天主角——連結串列就要來的隨性多,簡單的理解可以是這樣:在記憶體中,棧和佇列(陣列)的存在就是一個整體,如果想要對她內部某一個元素進行移除或是新增一個新元素,就要動她內部所有的元素,所謂牽一髮而動全身;而連結串列則不一樣,每一個元素都是由元素本身資料和指向下一個元素的指標構成,所以新增或是移除某一個元素不需要對連結串列整體進行操作,只需要改變相關元素的指標指向就可以了。

連結串列在實際生活中的例子也有很多,比如自行車的鏈條,環環相扣,但新增或是移除某一個環節只需要對症下藥,對相關環節進行操作就OK。再比如:火車,火車就是一個連結串列,每一節車廂就是元素,想要移除或是新增某一節車廂,只需要把連線車廂的鏈條改變一下就好了。那麼,在 JS 中又該怎麼去實現連結串列結構呢?

連結串列的建立

首先我們要建立一個連結串列類:

然後我們需要一種資料結構來儲存連結串列裡面的資料:

接下來,我們需要給連結串列宣告一些方法:

  • append(element):向連結串列尾部新增一個新的元素;
  • insert(position,element):向連結串列特定位置插入元素;
  • remove(element):從連結串列移除一項;
  • indexOf(element):返回連結串列中某元素的索引,如果沒有返回-1;
  • removeAt(position):從特定位置移除一項;
  • isEmpty():判斷連結串列是否為空,如果為空返回true,否則返回false;
  • size():返回連結串列包含的元素個數;
  • toString():重寫繼承自Object類的toString()方法,因為我們使用了Node類;

連結串列的完整程式碼:

ES6版本:

雙向連結串列

雙向連結串列和單項比起來就是Node類多了一個prev屬性,也就是每一個node不僅僅有一個指向它後面元素的指標也有一個指向它前面的指標。

迴圈連結串列

明白了前面的基礎連結串列和雙向連結串列之後這個肯定不在話下了,迴圈,其實就是整個連結串列例項變成了一個圈,在單項鍊表中最後一個元素的next屬性為null,現在讓它指向第一個元素也就是head,那麼他就成了單向迴圈連結串列。在雙向連結串列中最後一個元素的next屬性為null,現在讓它指向第一個元素也就是head,那麼他就成了雙向迴圈連結串列。就那麼回事…

後記

說到現在一直都是線性表,就是順序資料結構,他們都是有順序的,資料都是一條繩子上的螞蚱。那麼,如果資料是沒有順序的呢?那又該使用哪種資料結構呢?這個放到[學習javascript資料結構(三)——集合]中學習。

打賞支援我寫出更多好文章,謝謝!

打賞作者

打賞支援我寫出更多好文章,謝謝!

任選一種支付方式

學習 JS 資料結構(2):連結串列 學習 JS 資料結構(2):連結串列

相關文章