一、双向链表 双向链表和普通链表的区别在于,普通链表的节点只能指向下一个节点,而双向链表可以指向上一个节点。 1.创建双向链表(下面代码和链表(一)中代码写法不一样,只是单纯的想换种写法而已) fun
一、双向链表
双向链表和普通链表的区别在于,普通链表的节点只能指向下一个节点,而双向链表可以指向上一个节点。
1.创建双向链表(下面代码和链表(一)中代码写法不一样,只是单纯的想换种写法而已)
function DoublyLinkedList(){ this.length = 0; this.head = null; //头 this.tail = null; //尾}function Node(element){ this.element = element; this.next = null; this.prev = null;}
(1)节点类型要有三个属性,元素值element,访问下一个节点的属性next,访问前一节点的属性prev
(2)双向链表类型要有两个属性,头head,尾tail,用于其他操作的开始
2.在任一位置插入一个新元素
DoublyLinkedList.prototype.insert = function(position,element){ if(position >= 0 && position <= this.length){ var node = new Node(element), current = this.head, previous, index = 0; if(position === 0){ if(!this.head){ //如果链表为空 this.head = node; this.tail = node; }else{ node.next = current; current.prev = node; this.head = node; } }else if(position === this.length){ current = this.tail; current.next = node; node.prev = current; this.tail = node; }else{ while(index++ < position){ previous = current; current = current.next; } node.next = current; previous.next = node; current.prev = node; node.prev = previous; } this.length++; return true; }else{ return false; } };
(1)双向链表,有head和tail,因此不光要判断插入位是否0,还要判断插入位是否是末位。前者是重新赋head值,后者是重新赋tail值
(2)插入位为0时,要判断是否链表中是否有节点,无节点时,head和tail都是node节点,有节点时,node.next = current;current.prev = node;this.head = node;拼接好之后,给head赋值。
3.从任一位置移除一个元素
//从任意位置移除元素 DoublyLinkedList.prototype.removeAt = function(position){ //检查越界值 if(position > -1 && position < this.length){ var current = this.head, previous, index = 0; //移除第一项 if(position === 0){ //第一项 this.head = current.next; if(this.length === 1){ this.tail = null }else{ this.head.prev = null; } }else if(position === this.length-1){ //最后一项 current = this.tail; this.tail = current.prev; this.tail.next = null; }else{ while(index++ < position){ previous = current; current = current.next; } //将previous与current的下一项连接起来——跳过current previous.next = current.next; current.next.prev = previous; } this.length--; return current.element; }else{ return null; } };
(1)参数:position
(2)判断移除位置是0还是末位,因为这两个点要重新赋head或tail值
4.返回链表项
//返回链表项——正序 DoublyLinkedList.prototype.toString = function(){ var current = this.head, string = ''; while(current){ string += current.element+" "; current = current.next; } return string; };//返回链表项——逆序 DoublyLinkedList.prototype.toStringRe = function(){ var current = this.tail, string = ''; while(current){ string += current.element+" "; current = current.prev; } return string; };
(1)正序,从head开始,向后遍历
(2)逆序,从tail开始,向前遍历
5.使用双向链表
var doubleList = new DoublyLinkedList(); doubleList.insert(0,10); doubleList.insert(0,15); doubleList.insert(0,1); doubleList.insert(2,8); console.log(doubleList.length); console.log(doubleList.toString()); //1 15 8 10 doubleList.removeAt(1); console.log(doubleList.toStringRe()); //10 8 1 doubleList.removeAt(0); doubleList.removeAt(0); console.log(doubleList.toString()); //10
6.循环链表
单向循环链表就是tail的next是head
双向循环链表就是head的prev指向tail,tail的next是head