双向链表与普通链表的区别:在普通链表中,一个节点只有链向下一个节点的链接;而在双向链表中,链接是双向的,一个链向下一个元素,另一个链向前一个元素。
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();
结果如下: