鏈表

定義

鏈表是由一組節(jié)點(diǎn)組成。每個(gè)節(jié)點(diǎn)都使用一個(gè)對(duì)象的引用指向它的后繼。指向另一個(gè)節(jié)點(diǎn)的引用叫做鏈。

設(shè)計(jì)一個(gè)基于對(duì)象的鏈表

  1. Node類(lèi)
function Node(element) {
  this.element = element;
  this.next = null;
}
  1. LinkedList類(lèi)
function LList () {
    this.head = new Node("head");
    this.find = find;
    this.insert = insert;
    this.remove = remove;
    this.display = display;
}

實(shí)現(xiàn)方法

我們首先實(shí)現(xiàn) insert 方法, 但是實(shí)現(xiàn)insert方法之前可以先實(shí)現(xiàn) find 方法,先找到已知節(jié)點(diǎn),然后將新節(jié)點(diǎn)插入到已知節(jié)點(diǎn)后:

function find(item) {
    var currentNode = this.head;
    while(currentNode.element!=item) {
        currentNode = currentNode.next
    }
    return currentNode;
}

現(xiàn)在就可以實(shí)現(xiàn)insert方法了:

function insert(newElement, item) {
    var newNode = new Node(newElement);
    var current = this.find(item);
    newNode.next = current.next;
    current.next = newNode;
}

展示所有數(shù)據(jù)的 display 方法:

function display() {
    var currentNode = this.head;
    while(currentNode != null) {
        console.log(currentNode.element);
        currentNode = currentNode.next;
    }
}

測(cè)試我們寫(xiě)的方法:

var cities = new LList();
cities.display();
cities.insert('second', 'head');
cities.insert('third', 'second');
cities.insert('second-third', 'second');
cities.display();
結(jié)果

我們似乎還少寫(xiě)了一個(gè) remove 方法,從鏈表中刪除節(jié)點(diǎn)時(shí),需要找到待刪除節(jié)點(diǎn)前面的節(jié)點(diǎn)。找到這個(gè)節(jié)點(diǎn)后修改它的 next 屬性,使其不再指向待刪除的節(jié)點(diǎn),而是指向待刪除節(jié)點(diǎn)的下一個(gè)節(jié)點(diǎn)。我們可以先寫(xiě)一個(gè)findprevious方法:

function findPrevious(item) {
    var currentNode = this.head;
    while(currentNode.next != null && currentNode.next.element != item) {
        console.log(currentNode.next);
        currentNode = currentNode.next;
    }
    return currentNode;
}

所以,現(xiàn)在可以寫(xiě)remove 方法了:

function remove(item) {
    var currentNode = this.findPrevious(item);
    if (currentNode.next != null) {
        currentNode.next = currentNode.next.next;
    }
}

現(xiàn)在可以來(lái)測(cè)試下我們寫(xiě)的remove 方法了。

cities.remove('second');
console.log('刪除second后:');
cities.display();
結(jié)果

雙向鏈表

首先我們需要給Node類(lèi)增加一個(gè) previous 屬性:

function Node(element) {
    this.element = element;
    this.next = null;
    this.previous = null;
}

由于現(xiàn)在節(jié)點(diǎn)多了一個(gè) previous 屬性,所以需要改造下 insert 方法:

function insert(newElement, item) {
    var currentNode = this.find(item);
    var newNode = new Node(newElement);
    newNode.previous = currentNode;
    newNode.next = currentNode.next;
    currentNode.next.previous = newNode;
    currentNode.next = newNode;
}

雙向鏈表的 remove 方法比單向鏈表的效率更高,因?yàn)椴恍枰俨檎仪膀?qū)節(jié)點(diǎn)了,首先要在鏈表中查找待刪除的節(jié)點(diǎn),然后再設(shè)置該節(jié)點(diǎn)前驅(qū)節(jié)點(diǎn)的 next 屬性,使其指向待刪除節(jié)點(diǎn)的后驅(qū)節(jié)點(diǎn)就好了。

function remove(element) {
    var currentNode = this.find(element);
    if (currentNode.next != null) {
        currentNode.previous.next = currentNode.next;
        currentNode.next.previous = currentNode.previous;
        currentNode.next = null;
        currentNode.previous = null;
    }
}

最后我們?cè)賹?shí)現(xiàn)一個(gè)反向打印鏈表的方法,就基本完成了鏈表的基本方法實(shí)現(xiàn),實(shí)現(xiàn)這個(gè)方法之前我們需要實(shí)現(xiàn)一個(gè) findLast 方法來(lái)查找鏈表最后一個(gè)節(jié)點(diǎn):

findLast() {
    var currentNode = this.head;
    while(currentNode.next != null)  {
        currentNode = currentNode.next;
    }
    return currentNode;
}

這時(shí)候我們就可以很容易實(shí)現(xiàn)反向打印鏈表了:


function dispReverse() {
    var lastNode = this.findLast();
    while(lastNode.previous != null) {
        console.log(lastNode.element);
        lastNode = lastNode.previous;
    }
    console.log(lastNode.element);
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • //leetcode中還有花樣鏈表題,這里幾個(gè)例子,冰山一角 求單鏈表中結(jié)點(diǎn)的個(gè)數(shù)----時(shí)間復(fù)雜度O(n)這是最...
    暗黑破壞球嘿哈閱讀 1,540評(píng)論 0 6
  • 鏈表(Linked-list) 前面我們討論了如何使用棧、隊(duì)列進(jìn)行存數(shù)數(shù)據(jù),他們其實(shí)都是列表的一種,底層存儲(chǔ)的數(shù)據(jù)...
    Cryptic閱讀 38,940評(píng)論 7 57
  • JS中可以動(dòng)態(tài)的向數(shù)組中添加刪除元素,所以不需要鏈表結(jié)構(gòu)。鏈表特點(diǎn): 添加、刪除元素很快,不需要進(jìn)行移動(dòng)。 單鏈表...
    xiaoguo16閱讀 310評(píng)論 0 0
  • 鏈表 概念 說(shuō)到鏈表,coder們都不會(huì)陌生,在日常開(kāi)發(fā)中或多或少都會(huì)用到它。它是鏈?zhǔn)酱鎯?chǔ)的線性表,簡(jiǎn)稱(chēng)鏈表。鏈表...
    扈扈哈嘿閱讀 2,089評(píng)論 0 5
  • Excel作為一種人盡皆知的數(shù)據(jù)處理的工具,但是能把它真正用好的卻是不多,在大學(xué)計(jì)算機(jī)課中學(xué)過(guò),也專(zhuān)門(mén)照著一些EX...
    橘子俠閱讀 948評(píng)論 0 1