存储多个元素,最常用的数据结构是数组。但是数组有个一缺点,从数组中添加或移除项的成本很高,因为需要移动元素。链表也可以存储有序的元素集合,但是和数组不同,链表中的元素在内存中不是连续放置的。每个元素存储本身节点值和下一个元素的引用,链表的一个好处在于,添加或移除元素的时候不需要移动其他元素。
ok,开始实现我们的数据结构,骨架如下
function LinkedList() {
var Node = function (val) {
this.val = val;
this.next = null;
}; //Node辅助类
var length = 0;
var head = null;
this.append = function (ele) {}; //追加
this.insert = function (pos, ele) {}; //插入
this.removeAt = function (pos) {}; //移除
this.indexOf = function (ele) {}; //查找元素
this.isEmpty = function () {}; //是否为空
this.size = function () {}; //链表元素个数
this.getHead = function () {}; //链表头
this.toString = function () {}; //转换为字符串
}
首先实现向链表尾部追加元素吧:
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++; //更新链表长度
}
继续实现链表插入
this.insert = function (pos, ele) {
var node = new Node(ele);
var idx = 0,
previous,
current = head;
// 检查是否越界
if (pos >= 0 && pos <= length) {
if (pos === 0) {
node.next = current;
head = node;
} else {
while (idx < pos) {
previous = current; //保存前一个节点的引用
current = current.next;
idx++;
}
node.next = current; //节点的next指向current
previous.next = node; //前一个节点指向node
length++; //更新数组长度
}
} else {
return false;
}
}
链表的移除:
this.removeAt = function (pos) {
var current = head;
var idx = 0,
previous;
//检查越界
if (pos >= 0 && pos <= length) {
if (pos === 0) {
head = current.next;
} else {
while (idx < pos) {
previous = current;
current = current.next;
idx++;
}
previous.next = current.next; //前一个节点指向下一个节点
}
length--; //更新链表长度
return current.val;
} else {
return null
}
}
其他方法就比较简单了,实现如下:
this.isEmpty = function () {
return !length;
}
this.size = function () {
return length;
}
this.getHead = function () {
return head;
}
this.toString = function () {
var str = '';
var current = head;
while (current) {
str = str + ',' + current.val;
current = current.next;
}
return str.slice(1);
}