forked from XPoet/js-data-structure-and-algorithm
-
Notifications
You must be signed in to change notification settings - Fork 0
/
doublyLinkedList.js
202 lines (158 loc) · 4.91 KB
/
doublyLinkedList.js
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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
import { LinkedList, Node } from '../LinkedList/linkedList';
// 双向链表结构的封装
// 双向链表的节点类(继承单向链表的节点类)
class DoublyNode extends Node {
constructor(element) {
super(element);
this.prev = null;
}
}
// 双向链表类(继承单向链表类)
export class DoublyLinkedList extends LinkedList {
constructor() {
super();
this.tail = null;
}
// ------------ 链表的常见操作 ------------ //
// append(element) 往双向链表尾部追加一个新的元素
// 重写 append()
append(element) {
// 1、创建双向链表节点
const newNode = new DoublyNode(element);
// 2、追加元素
if (this.head === null) {
this.head = newNode;
this.tail = newNode;
} else {
// !!跟单向链表不同,不用通过循环找到最后一个节点
// 巧妙之处
this.tail.next = newNode;
newNode.prev = this.tail;
this.tail = newNode;
}
this.length++;
}
// insert(position, data) 插入元素
// 重写 insert()
insert(position, element) {
// 1、position 越界判断
if (position < 0 || position > this.length) return false;
// 2、创建新的双向链表节点
const newNode = new DoublyNode(element);
// 3、判断多种插入情况
if (position === 0) { // 在第 0 个位置插入
if (this.head === null) {
this.head = newNode;
this.tail = newNode;
} else {
//== 巧妙之处:相处腾出 this.head 空间,留个 newNode 来赋值 ==//
newNode.next = this.head;
this.head.perv = newNode;
this.head = newNode;
}
} else if (position === this.length) { // 在最后一个位置插入
this.tail.next = newNode;
newNode.prev = this.tail;
this.tail = newNode;
} else { // 在 0 ~ this.length 位置中间插入
let targetIndex = 0;
let currentNode = this.head;
let previousNode = null;
// 找到要插入位置的节点
while (targetIndex++ < position) {
previousNode = currentNode;
currentNode = currentNode.next;
}
// 交换节点信息
previousNode.next = newNode;
newNode.prev = previousNode;
newNode.next = currentNode;
currentNode.prev = newNode;
}
this.length++;
return true;
}
// getData() 继承单向链表
getData(position) {
return super.getData(position);
}
// indexOf() 继承单向链表
indexOf(data) {
return super.indexOf(data);
}
// removeAt() 删除指定位置的节点
// 重写 removeAt()
removeAt(position) {
// 1、position 越界判断
if (position < 0 || position > this.length - 1) return null;
// 2、根据不同情况删除元素
let currentNode = this.head;
if (position === 0) { // 删除第一个节点的情况
if (this.length === 1) { // 链表内只有一个节点的情况
this.head = null;
this.tail = null;
} else { // 链表内有多个节点的情况
this.head = this.head.next;
this.head.prev = null;
}
} else if (position === this.length - 1) { // 删除最后一个节点的情况
currentNode = this.tail;
this.tail.prev.next = null;
this.tail = this.tail.prev;
} else { // 删除 0 ~ this.length - 1 里面节点的情况
let targetIndex = 0;
let previousNode = null;
while (targetIndex++ < position) {
previousNode = currentNode;
currentNode = currentNode.next;
}
previousNode.next = currentNode.next;
currentNode.next.perv = previousNode;
}
this.length--;
return currentNode.data;
}
// update(position, data) 修改指定位置的节点
// 重写 update()
update(position, data) {
// 1、删除 position 位置的节点
const result = this.removeAt(position);
// 2、在 position 位置插入元素
this.insert(position, data);
return result;
}
// remove(data) 删除指定 data 所在的节点(继承单向链表)
remove(data) {
return super.remove(data);
}
// isEmpty() 判断链表是否为空
isEmpty() {
return super.isEmpty();
}
// size() 获取链表的长度
size() {
return super.size();
}
// forwardToString() 链表数据从前往后以字符串形式返回
forwardToString() {
let currentNode = this.head;
let result = '';
// 遍历所有的节点,拼接为字符串,直到节点为 null
while (currentNode) {
result += currentNode.data + '--';
currentNode = currentNode.next;
}
return result;
}
// backwardString() 链表数据从后往前以字符串形式返回
backwardString() {
let currentNode = this.tail;
let result = '';
// 遍历所有的节点,拼接为字符串,直到节点为 null
while (currentNode) {
result += currentNode.data + '--';
currentNode = currentNode.prev;
}
return result;
}
}