一、双向链表
- 他和普通链表的区别,在双向链表中,链接是双向的,一个链向下一个元素一个链向上一个元素。在操作双向链表的时候既要像普通链表一样考虑next,也要考虑prev。
- 双向列表提供了两种迭代列表的方法:从头到尾迭代,或者反过来。

function DoublyLinkedList(){
var head = null;
var len = 0;
var tail = null;
var Node = function(_data){
this.data = _data;
this.next = null;
this.prev = null;
};
this.insert = function(position, _data) {
if(position >= 0 && position <= len) {
var node = new Node(_data),
current = head,
previous,
index = 0;
if(position === 0) { //在第一个位置添加
if(!head) { //如果head不存在即链表为空
head = node;
tail = node;
} else { //链表不为空
node.next = current;
current.prev = node;
head = node;
}
} else if(position === len) { //在最后一个位置添加
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;
}
len ++; //更新列表长度
return true;
} else {
return false;
}
};
this.removeAt = function(position) {
if(position > -1 && position < len) { //检查越界值
var current = head,
previous,
index = 0;
if(position === 0) { //第一个位置
head = current.next;
if(len === 1) { //如果链表只有一项
tail = null;
} else { //也就相当于把current.next.prev = null
head.prev = null;
}
} else if(position === len -1) { //最后一项
current = tail; //tail的引用赋给current变量
tail = current.prev; //上一项指向tail
tail.next = null; //最后一项的next都是指向null的
} else {
while(index++ < position) { //从中间位置移除
previous = current;
current = current.next;
}
previous.next = current.next; //直接跳过current连接上一项和下一项
current.next.prev = previous;
}
current = null;
len --;
return true;
} else {
return null;
}
}
}
二、循环链表
- 单向循环链表和链表唯一去别在于:最后一个元素指向下一个元素的指针(tail.next)不是引用null而是指向第一个元素(head)

- 双向循环链表有指向head的tail.next,也有指向tail的head.prev
