链表
相对于传统的数组,链表的一个好处在于,添加或移除元素的时候不需要移动其他元素。
5.1 创建一个链表
function LinkedList() {
var Node = function(ele) {
this.ele = ele;
this.next = null;
};
var length = 0;
var head = null;
// 5.1.1 向列表尾部添加一项
this.append = function(ele) {
var node = new Node(ele),
current;
if (head === null) {
head = node;
} else {
current = head;
// 循环列表,直到找到最后一项
while (current.next) {
current = current.next;
}
// 找到最后一项,将其next赋为node,建立链接
current.next = node;
}
length++; // 更新列表长度
};
// 5.1.2 根据特定位置移除一个元素
this.removeAt = function(pos) {
// 检查越界值
if (pos > -1 && pos < length) {
var current = head,
prev,
index = 0;
// 移除第一项
if (pos === 0) {
head = current.next;
} else {
while (index++ < pos) {
prev = current;
current = current.next;
}
// 将prev与current的下一项链接起来:跳过current,从而移除它
prev.next = current.next;
}
length--;
return current.ele;
} else {
return null;
}
};
// 5.1.3 在任意位置插入一个元素
this.insert = function(pos, ele) {
// 检查越界值
if (pos >= 0 && pos <= length) {
var node = new Node(ele),
current = head,
prev,
index = 0;
// 在第一个位置添加
if (pos === 0) {
node.next = current;
head = node;
} else {
while (index++ < pos) {
prev = current;
current = current.next;
}
node.next = current;
prev.next = node;
}
length++;
return true;
} else {
return false;
}
};
// 5.1.4 实现其他方法
// 1.toString方法
this.toString = function() {
var current = head,
str = '';
while (current) {
str += ',' + current.ele;
current = current.next;
}
return str.slice(1);
};
// 2.indexOf方法
this.indexOf = function(ele) {
var current = head,
index = 0;
while (current) {
if (ele === current.ele) {
return index;
}
index++;
current = current.next;
}
return -1;
};
// 3.remove方法
this.remove = function(ele) {
var index = this.indexOf(ele);
return this.removeAt(index);
};
// 4.isEmpty,size,和getHead方法
this.isEmpty = function() {
return length === 0;
};
this.size = function() {
return length;
};
this.getHead = function() {
return head;
};
}
5.2 双向链表
双向链表提供了两种迭代列表的方法:从头到尾,或反过来
优点: 在单向链表中,如果迭代列表时错过了要找的元素,就需要从头再来,双向链表则不需要如此
function DoublyLinkedList() {
var Node = function(ele) {
this.ele = ele;
this.next = null;
this.prev = null; // 新增的
}
var length = 0;
var head = null;
var tail = null; // 新增的
// 5.2.1 在任意位置插入一个新元素
this.insert = function (pos, ele) {
// 检查越界值
if (pos >= 0 && pos <= length) {
var node = new Node(ele),
current = head,
prev,
index = 0;
if (pos === 0) { // 在第一个位置添加
if (!head) {
head = node;
tail = node;
} else {
node.next = current;
current.prev = node;
head = node;
}
} else if (pos === length) {
current = tail;
current.next = node;
node.prev = current;
tail = node;
} else {
while (index++ < pos) {
prev = current;
current = current.next;
}
node.next = current;
prev.next = node;
current.prev = node;
node.prev = prev;
}
length++;
return true;
} else {
return false;
}
}
// 5.2.2 从任意位置移除元素
this.removeAt = function(pos) {
if (pos > -1 && pos < length) {
var current = head,
prev,
index = 0;
// 移除第一项
if (pos === 0) {
head = current.next;
if (length === 1) {
tail = null;
} else {
head.prev = null;
}
} else if (pos === length - 1) {
current = tail;
tail = current.prev;
tail.next = null;
} else {
while (index++ < pos) {
prev = current;
current = current.next;
}
prev.next = current.next;
current.next.prev = prev;
}
length--;
return current.ele;
} else {
return null;
}
};
}