《Javascript数据结构和算法》笔记-「链表」

JavaScript-链表

《Javascript数据结构与算法》第五章

5.1 链表数据结构

链表差别与数组

  • 数组要插进去或许移入一个元素的本钱很高,因为一切元素都须要挪动位置。
  • 链表插进去或许挪动一个元素时很高效,因为并不须要挪动其他的元素位置。

链表存储元素的体式格局,在内存中不是有递次的,每个元素由

  • 1.存储元素自身的节点
  • 2.指向一下元素的指针构成

5.2 建立链表

5.2.0 建立链表的骨架

  • 1.链表须要有一个 Node 类,示意要到场链表的项,它包含 2 个部份,一个是该项的值,和一个只想下一项的指针
  • 2.链表还须要个示意链表长度的属性 length
  • 3.示意第一项的援用 head
  • 4.和一系列增编削查、查询长度的要领
function LinkedList() {
    function Node(element) {
        this.element = element;
        this.next = null;
    }

    this.length = 0;
    this.head = null;

    this.append = function(element) {};
    this.insert = function(position, element) {};
    this.remove = function(position) {};
}

5.2.1 append,向链表尾部增加元素

this.append = function(element) {
    var node = new Node(element); //此时node实例 {element:'111',next:null}

    this.length + 1;

    if (this.head === null) {
        this.head = node;
    } else {
        //插进去到末了一项,然则因为没有递次,所以我们没法直接获得链表的末了一项,只能while轮回next为null
        let lastNode = head;
        while (lastNode.next !== null) {
            lastNode = lastNode.next;
        }
        lastNode.next = node;
    }
};

5.2.2 removeAt 从链表中删除元素

思绪就是分 2 个状况

  • 假如要删除第 0 项,就把 head 指向 head.next 就好了
  • 假如要删除第 n 项,须要 while 轮回找到这当前这个 current 项目,将 current 的前一项的 next,超出 current,指向指向 current 的下一项

如许当前元素被抛弃在计算机内存中,就等着被渣滓接纳机制,本身接纳了。

this.removeAt = function(position) {
    // 搜检是不是position参数的边境
    if (position > -1 && position < length) {
        let current = head,
            previous, // 示意position上一项元素
            index = 0;

        if (position === 0) {
            head = current.next;
        } else {
            // 假如index++,一直到index追上position时,那末这个current就是position索引对应的元素了
            while (index++ < position) {
                previous = current;
                current = current.next;
            }
            // 让position对应的元素的,上一项的next,超出要删除的这一项,直接指向下一项元素就好了
            previous.next = current.next;
        }
        length--;
        return current;
    } else {
        return null;
    }
};

5.2.3 insert 在某个位置插进去

this.insert = function(position, element) {
    if (position >= 0 && position < length) {
        let node = new Node(element);
        let index = 0;
        let current = head;
        let previous;
        if (position === 0) {
            node.next = current;
            head = node;
        } else {
            while (index++ < position) {
                previous = current;
                current = current.next;
            }
            node.next = current;
            previous.next = node;
        }
        length++;
        return true;
    } else {
        return false;
    }
};

5.2.4 toString 打印链表

this.toString = function() {
    let current = head;
    let str = "";
    while (current) {
        str += current.element + (current.next ? " - " : "");
        current = current.next;
    }
    return str;
};

5.2.5 size 猎取链表长度

this.size = function() {
    return length;
};

双向链表骨架

以上是单向链表的JS完成,实际上链表另有多种差别的范例,比方双向链表、轮回链表

双向链表和单向链表的一个区分在于,每个item,不单单议包含value和next指针,还包含prev指针

同时双向链表不单单议保留head,也保留末了一项的援用。

如许的优点是: 迭代单向链表时,假如错过了某一项,只能从新迭代,然则双向链表就找到上一项

function DoublyLinkedList(){
    let Node = function(){
        this.element = element;
        this.next = null;
        this.prev = null;  // 指向上一项的指针
    }

    let length = 0;
    let head = null;
    let tail = null;  // 保留末了一项的索引
}

轮回链表

轮回链表,是指末了一项的指针不是null,而是指向第一个元素的一种链表。

所以轮回链表,有多是单向链表,也多是双向链表

双向轮回链表,末了一项的指针指向head,第一项的指针指向tail

    原文作者:Ziwei
    原文地址: https://segmentfault.com/a/1190000017062874
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞