学习JavaScript数据结构与算法(四)——双向链表

来源:互联网 发布:端口类型有几种 编辑:程序博客网 时间:2024/06/07 11:56

双向链表与普通链表的区别:在普通链表中,一个节点只有链向下一个节点的链接;而在双向链表中,链接是双向的,一个链向下一个元素,另一个链向前一个元素。

双向链表

function DoublyLinkedList () {    var Node = function(element){        this.element = element;        this.next = null;        this.prev = null;//一个新指针,指向前一个  //新增的    };    var length = 0;    var head = null;    var tail = null;//对列表最后一项的引用  //新增的    /*下面是方法*/}

1、在任意位置插入一个新元素

与普通链表的区别:在普通链表只要控制一个next指针;而双向链表要同时控制next和prev两个指针。

this.insert = function(position, element){    //检查越界值    if (position >= 0 && position <= length) {        var node = new Node(element),            current = head,            previous,            index = 0;        //在列表的起点添加一个元素        if (position === 0) {            if (!head) {//新增的                head = node;                tail = node;            }            else {                node.next = current;                current.prev = node;//新增的                head = node;            }        }        //在列表最后添加一个新元素        else if (position === length) {//新增的            current = tail;            current.next = node;            node.prev = current;            tail = node;        }        //在列表中间或尾部添加一个元素        else {            while (index++ < position) {                previous = current;                current = current.next;            }            node.next = current;            previous.next = node;            current.prev = node;//新增的            node.prev = previous;//新增的        }        length++;//更新列表长度        return true;    }    //越界就返回false,表示没有添加项到列表中    else {        return false;    }};

2、从任意位置移除元素

区别在于还需要设置前一个位置的指针。

this.removeAt = function(position){    //检查越界值    if (position > -1 && position < length) {        var current = head,            previous,            index = 0;        //移除第一项        if (position === 0) {            head = current.next;            //如果只有一项,更新tail  //新增的            if (length === 1) {                tail = null;            }            else {                head.prev = null;            }        }        //移除最后一项        else if (position === length-1) {//新增的            current = tail;            tail = current.prev;            tail.next = null;        }        else {            while (index++ < position) {                previous = current;                current = current.next;            }            /*            current是对要移除元素的引用            previous是对要移除元素的前一个元素的引用            要移除current,只需将previous与current的下一项链接起来             */            previous.next = current.next;            current.next.prev = previous;//新增的        }        length--;        return current.element;    }    //不是有效位置,返回null    else {        return null;    }};

3、其他方法的实现

this.append = function(element){    var node = new Node(element),        current;    if (head === null){        head = node;        tail = node;  //新增的    }    else {        //新增的        tail.next = node;        node.prev = tail;        tail = node;    }    length++;};this.remove = function(element){    var index = this.indexOf(element);    return this.removeAt(index);};this.indexOf = function(element){    var current = head,        index = -1;    //检查第一项    if (element == current.element){        return 0;    }    index++;    //检查列表中间的元素    while(current.next){        if (element == current.element){            return index;        }        current = current.next;        index++;    }    //检查最后一项    if (element == current.element){        return index;    }    return -1;};this.isEmpty = function() {    return length === 0;};this.size = function() {    return length;};this.toString = function(){    var current = head,        s = current ? current.element : '';    while(current && current.next){        current = current.next;        s += ', ' + current.element;    }    return s;};this.inverseToString = function() {    var current = tail,        s = current ? current.element : '';    while(current && current.prev){        current = current.prev;        s += ', ' + current.element;    }    return s;};this.print = function(){    console.log(this.toString());};this.printInverse = function(){    console.log(this.inverseToString());};this.getHead = function(){    return head;};this.getTail = function(){    return tail;};

测试代码如下:

var list = new DoublyLinkedList();list.append(15);list.print();list.printInverse();list.append(16);list.print();list.printInverse();list.append(17);list.print();list.printInverse();list.insert(0,13);list.print();list.printInverse();list.insert(4,18);list.print();list.printInverse();list.insert(1,14);list.print();list.printInverse();list.removeAt(0);list.print();list.printInverse();list.removeAt(list.size()-1);list.print();list.printInverse();list.removeAt(1);list.print();list.printInverse();list.remove(16);list.print();list.printInverse();list.remove(14);list.print();list.printInverse();list.remove(17);list.print();list.printInverse();

结果如下:

使用DoublyLinkedList类

原创粉丝点击