js实现双向链表

1.概念工具

  上一个文章里咱们已经了解到链表结构,链表的特色是长度不固定,不用担忧插入新元素的时候新增位置的问题。插入一个元素的时候,只要找到插入点就能够了,不须要总体移动整个结构。测试

  这里咱们了解一下双向链表的结构。尽管从链表中头节点遍历到尾节点很容易,可是反过来,从后向前遍历就没有那么简单。经过给Node对象增长一个属性,该属性存储指向前驱节点的连接,这样就容易多了。此时祥链表中插入一个节点须要更多的工做,咱们须要指出该节点正确的前驱和后续。可是在从链表中删除节点的时候效率更高了,不须要再查找待删除节点的前驱节点了。以下图1演示了双向链表的工做原理。this

图1spa

首先是要为Node类增长一个previouse属性,这个属性指向当前节点的前驱:code

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

  双向链表的insert()方法和单项链表的相似,可是须要设置新节点的previouse属性,是其指向该节点的前驱。该方法的定义以下:对象

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

  双向链表的删除remove()方法币单项链表的效率更高,由于不须要查找前驱节点了。首选须要在链表中找出存储待删除数据的节点,而后设置该节点的next属性,使其指向待删除节点的后续。设置该节点的后续的previouse的属性,使其指向待删除节点的前驱。以下图2展现删除节点的过程:blog

图2ci

remove()方法的定义以下:element

复制代码
function remove(item){
    var currNode = this.find(item);
    if(!(currNode.next == null)){
        currNode.previous.next = currNode.next;
        currNode.next.previous = currNode.previous;
        currNode.next = null;
        currNode.previous = null;
    }
}
复制代码

  为了实现反向显示链表中元素的任务,须要给链表增长一个工具方法,用来查找链表中最后一个节点。findLast()方法找出链表中最后一个节点,同时免除从前日后遍历之苦。以下:rem

复制代码
function findLast(){
    var currNode = this.head;
    while (!(currNode.next == null)){
        currNode = currNode.next;
    }
    return currNode;
}
复制代码

  有了这个工具方法以后就,就能够很容易的写出反向显示双向链表的元素的方法,dispReverse()方法以下所示:

复制代码
function dispReverse(){
    var currNode = this.head;
    currNode = this.findLast();
    while (!(currNode.previous == null)){
        document.write(currNode.element + ' ');
        currNode = currNode.previous;
    }
}
复制代码

 

2.代码实现

  双向链表就上面一些特性,下面是完整的代码实现和测试代码:

复制代码
function Node(element){
    this.element = element;
    this.next = null;
    this.previous = null;
}

function LList(){
    this.head = new Node('head');
    this.find = find;
    this.insert = insert;
    this.display = display;
    this.remove = remove;
    this.findLast = findLast;
    this.dispReverse = dispReverse;
}

function dispReverse(){
    var currNode = this.head;
    currNode = this.findLast();
    while (!(currNode.previous == null)){
        document.write(currNode.element + ' ');
        currNode = currNode.previous;
    }
}

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

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

function display(){
    var currNode = this.head;
    while (!(currNode.next == null)){
        document.write(currNode.next.element + ' ');
        currNode = currNode.next;
    }
}

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

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


var cities = new LList();
cities.insert('Conway','head');
cities.insert('Russellville', 'Conway');
cities.insert('Carlisle', 'Russellville');
cities.insert('Alma' , 'Carlisle');
cities.display();
document.write('<br>');
cities.remove('Carlisle');
cities.display();
document.write('<br>');
cities.dispReverse();
复制代码
相关文章
相关标签/搜索