# 5. 链表
链表是一个线性结构,同时也是一个天然的递归结构。链表结构可以充分利用计算机内存空间,实现灵活的内存动态管理。

class Node {
constructor(v, next) {
this.value = v;
this.next = next;
}
}
class LinkList {
constructor() {
// 链表长度
this.size = 0;
// 虚拟头部
this.dummyNode = new Node(null, null);
}
find(header, index, currentIndex) {
if (index === currentIndex) return header;
return this.find(header.next, index, currentIndex + 1);
}
addNode(v, index) {
this.checkIndex(index);
// 当往链表末尾插入时,prev.next 为空
// 其他情况时,因为要插入节点,所以插入的节点
// 的 next 应该是 prev.next
// 然后设置 prev.next 为插入的节点
let prev = this.find(this.dummyNode, index, 0);
prev.next = new Node(v, prev.next);
this.size++;
return prev.next;
}
insertNode(v, index) {
return this.addNode(v, index);
}
addToFirst(v) {
return this.addNode(v, 0);
}
addToLast(v) {
return this.addNode(v, this.size);
}
removeNode(index, isLast) {
this.checkIndex(index);
index = isLast ? index - 1 : index;
let prev = this.find(this.dummyNode, index, 0);
let node = prev.next;
prev.next = node.next;
node.next = null;
this.size--;
return node;
}
removeFirstNode() {
return this.removeNode(0);
}
removeLastNode() {
return this.removeNode(this.size, true);
}
checkIndex(index) {
if (index < 0 || index > this.size) throw Error('Index error');
}
getNode(index) {
this.checkIndex(index);
if (this.isEmpty()) return;
return this.find(this.dummyNode, index, 0).next;
}
isEmpty() {
return this.size === 0;
}
getSize() {
return this.size;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
← 4. 队列