【js4agls】數據結構JavaScript描述-鏈表篇

以前咱們用數組的方式來實現了隊列,是否還記得在出隊列後有這樣一段代碼:javascript

for (i = 0; i < this.length - 1; i++) {
    this.dataStore[i] = this.dataStore[i + 1];
}

咱們爲了刪除一個元素,致使了整個數組元素的前移,顯然這是很是低效的!尤爲是當元素不少時。咱們可使用鏈表這種數據結構,來刪除元素的時候而沒必要讓後面的元素向前移動。java

圖片描述

一個節點的上一個節點稱爲它的前驅,下一個節點即next指向的節點稱爲它的後繼節點,在簡單的單向鏈表中,第一個節點稱爲頭節點它沒有前驅節點,最後一個節點沒有後繼節點(爲NULL)。關於頭節點head實際上是無關緊要的,可是通常都會加上這個數據爲空的節點,保存當前鏈表信息,若是一個鏈表的頭節點找不到了,那麼將會致使整個鏈表的丟失。git

ADT

咱們來看抽象數據類型的結構:github

Node,單個節點
- element,節點數據
- next,下一個節點的指針

LinkList,鏈表的信息與方法
- insert,插入節點
- find,查找一個節點
- remove,刪除一個節點
- findPrevious,查找節點的前驅節點
- print,打印鏈表

JavaScript完整描述

function Node (element) {
    this.element = element;
    this.next = null;
}
function LinkList () {
    this.head = new Node('head');
}
LinkList.prototype = {
    constructor: LinkList,
    insert: function (target, element) {
        var newNode = new Node(target);
        var current = this.find(element);
        newNode.next = current.next;
        current.next = newNode;
        return this;
    },
    find: function (target) {
        var currentNode = this.head;
        while (currentNode.element !== target) {
            currentNode = currentNode.next;
        }
        return currentNode;
    },
    remove: function (element) {
        var preNode = this.findPrevious(element);
        if (preNode.next !== null) {
            preNode.next = preNode.next.next;
            return true;
        }
        return false;
    },
    findPrevious: function (element) {
        var current = this.head;
        while (current.next !== null && current.next.element !== element) {
            current = current.next;
        }
        return current;
    },
    print: function () {
        var current = this.head.next;
        var str = '';
        while (current) {
            str += current.element + '->';
            current = current.next;
        }
        console.log(str.substr(0, str.length-2));
    }
}

分析

插入節點

  1. 經過find方法找到要插入的節點位置target
  2. 建立新的節點
  3. 當前節點的next指向target的next
  4. target.next指向新節點

在插入的最後咱們返回了this是爲了方便進行鏈式插入。數組

算了直接看圖:數據結構

圖片描述

刪除節點

  1. 找到要刪除元素的前驅preNode
  2. 將preNode的下一個節點指向preNode的下一個節點(要刪除的節點)的下一個節點
若是遍歷整個鏈表都沒找到要刪除的節點將會返回最後一個節點,而最後一個節點的下一個節點是NULL,因此,這樣的刪除操做會失敗,返回false

測試

var list = new LinkList();
list.insert('jiavan1', 'head').insert('jiavan2', 'jiavan1').insert('jiavan3', 'jiavan2').insert('jiavan4', 'jiavan3');
list.print(); // jiavan1->jiavan2->jiavan3->jiavan4
list.remove('jiavan2'); // true
list.print(); // jiavan1->jiavan3->jiavan4
list.remove('none'); // false

這只是最簡單的一種鏈表,複雜點的還有雙向鏈表,循環鏈表,咱們將用另外的文章實現。測試

原文出處 https://github.com/Jiavan/jia... 以爲對你有幫助就給個star吧
相關文章
相關標籤/搜索