JavaScript 自己提供了十分好用的數據類型,以知足你們的平常使用。單靠 Array 和 Object 也的確足夠應付平常的絕大部分需求,這也致使了不少前端er對數據結構這一塊不是十分的瞭解。html
數據結構是 CS 的必修科目,前端這個圈子非科班的童鞋比例較高,相信不少人對數據結構的瞭解並很少。雖然本人大學讀的也是 CS,但那時候上課基本都在睡覺,數據結構也是學得一塌糊塗,如今也基本上全忘了。前端
那下面咱們來了解一下,如何用 JavaScript 來實現一個 單向鏈表 。數組
維基百科中,對鏈表的描述以下:數據結構
鏈表(Linked list)是一種常見的基礎數據結構,是一種線性表,可是並不會按線性的順序存儲數據,而是在每個節點裏存到下一個節點的指針(Pointer)。因爲沒必要須按順序存儲,鏈表在插入的時候能夠達到O(1)的複雜度,比另外一種線性表順序錶快得多,可是查找一個節點或者訪問特定編號的節點則須要O(n)的時間,而順序表相應的時間複雜度分別是O(logn)和O(1)。this
由此能夠知道,鏈表和數據相比,會具備一下優勢:spa
JavaScript 做爲一門動態語言,其中的數組也是動態數組,不須要預先分配內存的。在使用過程當中還能夠動態增減數組長度,這直接讓 Array 類型的適用範圍擴大了很多。prototype
數組在進行插入和刪除元素時,是十分麻煩的事情,而這方面倒是鏈表的優點。在查找元素的效率方面,鏈表就比不上數組那麼方便快捷了。設計
單向鏈表,是鏈表中最簡單的一種,其特色是鏈表的連接方向是單向的,對鏈表的訪問要經過順序讀取從頭部開始。3d
下面咱們看看 單向鏈表 的圖示:指針
能夠看到,鏈表中每個 item(元素) 都有兩個部分組成:data 和 next。其中 data 用於存儲數據,是真正的存儲區。而 next 用於存放地址,用於指向下一個 item。
下面咱們看看怎麼設計一個單向列表。
通常的單向列表,都具備如下的屬性和方法:
爲了方便實用,還提供了部分語法糖:
下面是 SinglyLinkedList 的類:
var SinglyLinkedList = function () { function SinglyLinkedList() { this.length = 0; this.first = null; this.last = null; } /** * 根據索引獲取 item * @param {Number} index 鏈表索引 * @returns {*} */ SinglyLinkedList.prototype.get = function (index) { if (typeof index !== 'number' || index < 0 || index >= this.length) { return undefined; } var item = this.first; for (var i = 0; i < index; i++) { item = item.next; } return item; }; /** * 根據索引設置 item 的內容 * @param {Number} index 鏈表索引 * @param {*} value 須要設置的值 * @returns {*} */ SinglyLinkedList.prototype.set = function (index, value) { if (typeof index !== 'number' || index < 0 || index >= this.length) { return false; } var item = this.get(index); item.data = value; return item; }; /** * 根據索引位置插入新的 item * @param {Number} index 鏈表索引 * @param {*} value 須要設置的值 * @returns {*} */ SinglyLinkedList.prototype.add = function (index, value) { if (typeof index !== 'number' || index < 0 || index > this.length || index === undefined) { return false; } var item = { data: value, next: null }; if (this.length > 0) { if (index === 0) { item.next = this.first; this.first = item; } else if (index === this.length) { this.last.next = item; this.last = item; } else { var prevItem = this.get(index - 1), nextItem = this.get(index); item.next = nextItem; prevItem.next = item; } } else { this.first = item; this.last = item; } this.length++; return item; }; /** * 根據索引刪除 item * @param {Number} index 鏈表索引 * @returns {boolean} */ SinglyLinkedList.prototype.remove = function (index) { if (typeof index !== 'number' || index < 0 || index >= this.length) { return false; } var item = this.get(index); if (this.length > 1) { if (index === 0) { this.first = item.next; } else if (index === this.length - 1) { this.last = this.get(this.length - 2); this.last.next = null; } else { this.get(index - 1).next = item.next; } } else { this.first = null; this.last = null; } item = null; this.length--; return true; }; /** * 清空整個單鏈表 * @returns {boolean} */ SinglyLinkedList.prototype.clear = function () { this.first = null; this.last = null; this.length = 0; return true; }; SinglyLinkedList.prototype.addFirst = function (value) { return this.add(0, value); }; SinglyLinkedList.prototype.addLast = function (value) { return this.add(this.length, value); }; SinglyLinkedList.prototype.removeFirst = function () { return this.remove(0); }; SinglyLinkedList.prototype.removeLast = function () { return this.remove(this.length - 1); }; SinglyLinkedList.prototype.toString = function () { var arr = [], item = {}; if (this.length) { do { item = item.next || this.get(0); arr.push(typeof item.data === 'object' ? JSON.stringify(item.data).replace(/\"/g, '') : item.data); } while (item.next); } return arr.join(' -> '); }; return SinglyLinkedList; }();
使用方法很簡單:
var sList = new SinglyLinkedList(); sList.addLast('a'); sList.addFirst(10); sList.addLast(3.14); sList.add(2, [1, 2]); sList.addLast({a: 1, b: 2}); console.log(sList.toString()); // "10 -> a -> [1,2] -> 3.14 -> {a:1,b:2}" console.log(sList.length); // 5 sList.removeFirst(); sList.removeLast(); console.log(sList.toString()); // "a -> [1,2] -> 3.14" console.log(sList.length); // 3
參考資料:
http://zh.wikipedia.org/wiki/%E9%93%BE%E8%A1%A8
http://www.cnblogs.com/skywang12345/p/3561803.html#a33
本文做者:Maple Jan