码迷,mamicode.com
首页 > 编程语言 > 详细

数据结构与算法之链表

时间:2019-06-15 13:29:43      阅读:84      评论:0      收藏:0      [点我收藏+]

标签:his   alt   建立   就是   linked   function   单向链表   图片   效率   

链表

JS中数组被实现成了对象,对比其他语言的数组效率很低。因此可以考虑使用链表来替代。除了对数据的随机访问,链表几乎可以用在任何使用以为数组的情况中。如果需要随机访问,数组仍然是更好的选择。

单向链表

链表是由一组节点组成的集合。 每个节点都使用一个对象的引用指向它的后继。 指向另一
个节点的引用叫做链。

遍历链表, 就是跟着链接, 从链表的首元素一直走到尾元素,下面最前面的节点叫做头节点,在最后面的尾元素指向一个null节点。

技术图片

//  节点类
function Node(element){
    this.element = element;
    this.next = null;
}

//  LinkedList类,建立一个新的链表
function LList(){
    this.head = new Node("head");
}
LList.prototype = {
    constructor: LList,
    find(element){
        var node = this.head;
        while(node.element != element){
            if(node.next){
                node = node.next;
            }else{
                return null;
            }
        }
        return node;
    },
    insert(newElement, item){  //在item后面插入新元素
        var current = this.find(item);
        var newNode = new Node(newElement);
        newNode.next = current.next;
        current.next = newNode;
    },
    remove(item){
        var preNode = this.findPrevious(item);
        if(preNode.next !== null){
            preNode.next = preNode.next.next;     
        }
    },
    display(){  //不显示头节点
        var current = this.head;
        while(current.next !== null){
            console.log(current.next.element);
            current = current.next;
        }
    },
    findPrevious(item){  //用来查找该值节点的前一个节点
        var current = this.head;
        while(current.next.element !== item){
            if(current.next !== null){
                current = current.next;
            }else{
                return null;
            }
        }
        return current;
    }
}
双向链表

技术图片

//  节点类
function Node(element){
    this.element = element;
    this.next = null;
    this.previous = null;
}

//  LinkedList类,建立一个新的链表
function LList(){
    this.head = new Node("head");
}
LList.prototype = {
    constructor: LList,
    find(element){
        var node = this.head;
        while(node.element != element){
            if(node.next){
                node = node.next;
            }else{
                return null;
            }
        }
        return node;
    },
    insert(newElement, item){  //在item后面插入新元素
        var current = this.find(item);
        var newNode = new Node(newElement);
        newNode.next = current.next;
        newNode.previous = current;
        current.next = newNode;
    },
    remove(item){  //双向链表删除节点效率更高了,因为不需要再查找前驱节点了
        var removeNode = this.find(item);
        if(removeNode){
            removeNode.previous.next = removeNode.next;
            removeNode.next.previous = removeNode.previous;
            removeNode.next = null;
            removeNode.previous = null;
        }
    },
    display(){  //不显示头节点
        var current = this.head;
        while(current.next !== null){
            console.log(current.next.element);
            current = current.next;
        }
    },
    findLast(){  //查找链表的最后一项
        var current = this.head;
        while(current.next !== null){
            current = current.next;
        }
        return current;
    },
    dispReverse(){
        var current = this.findLast();
        while(current.previous !== null){
            console.log(current.element);
            current = current.previous;
        }
    },
}
循环链表

循环链表和单向链表相似, 节点类型都是一样的。 唯一的区别是, 在创建循环链表时, 让其头节点的 next 属性指向它本身,这样插入节点都会使得链表的尾节点都指向头节点,形成一个循环链表。

技术图片

如果你希望可以从后向前遍历链表, 但是又不想付出额外代价来创建一个双向链表, 那么就需要使用循环链表。 从循环链表的尾节点向后移动, 就等于从后向前遍历链表。

避免无限循环,需要对方法进行修改:

//  节点类
function Node(element){
    this.element = element;
    this.next = null;
}

//  LinkedList类,建立一个新的链表
function LList(){
    this.head = new Node("head");
    this.head.next = this.head;
}
LList.prototype = {
    constructor: LList,
    find(element){
        var node = this.head;
        while(node.element != element){
            if(node.next === this.head){
                return null;
            }
            node = node.next;
        }
        return node;
    },
    insert(newElement, item){  //在item后面插入新元素
        var current = this.find(item);
        var newNode = new Node(newElement);
        newNode.next = current.next;
        current.next = newNode;
    },
    remove(item){
        var preNode = this.findPrevious(item);
        preNode.next = preNode.next.next;     
    },
    display(){  //不显示头节点
        var current = this.head;
        while(current.next !== this.head){
            console.log(current.next.element);
            current = current.next;
        }
    },
    findPrevious(item){  //用来查找该值节点的前一个节点
        var current = this.head;
        while(current.next.element !== item){
            if(current.next === this.head){
                return null;
            }
            current = current.next;
        }
        return current;
    }
}

数据结构与算法之链表

标签:his   alt   建立   就是   linked   function   单向链表   图片   效率   

原文地址:https://www.cnblogs.com/simpul/p/11027177.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!