class CNode {
constructor(data) {
this.prev = null;
this.data = data;
this.next = null;
}
}
class DoubleLinkList {
constructor() {
this.head = null;
this.tail = null;
this.len = 0;
}
append(ele) {
let newnode = new CNode(ele);
if (this.len == 0) {
//空链表
this.head = newnode;
this.tail = newnode;
} else {
newnode.prev = this.tail;
this.tail.next = newnode;
this.tail = newnode;
}
this.len++
}
insert(position, ele) {
if (position < 0 || position > this.len || !Number.isInteger(position)) return false
let newnode = new CNode(ele);
if (position == 0) {
if (this.len == 0) {
this.head = newnode;
this.tail = newnode;
} else {
newnode.next = this.head;
this.head.prev = newnode;
this.head = newnode;
}
this.len++
} else if (position == this.len) {
this.append(ele)
} else {
let current = this.head, index = 0;
while (index < position - 1) {
current = current.next;
index++
}
// 新节点练上去
newnode.prev = current;
newnode.next = current.next;
current.next = newnode;
newnode.next.prev = newnode;
this.len++
}
}
removeAt(position) {
if (position < 0 || position > this.len - 1 || !Number.isInteger(position)) return false
if (position == 0) {
this.head = this.head.next;
this.head.prev = null
} else if (position == this.len - 1) {
this.tail = this.tail.prev;
this.tail.next = null
} else {
let current = this.head, index = 0;
while (index < position - 1) {
current = current.next;
index++;
}
current.next = current.next.next;
current.next.prev = current
}
this.len--
}
indexOf(ele) {
let current = this.head,
index = 0;
while (index < this.len) {
if (current.data == ele) {
return index
} else {
current = current.next;
index++
}
}
return -1
}
remove(ele) {
let in1 = this.indexOf(ele);
this.removeAt(in1)
}
toAfterString() {
let current = this.head, index = 0, res = "";
while (index < this.len) {
res += '-' + current.data;
current = current.next;
index++
}
return res.slice(1)
}
toBeforeString() {
let current = this.tail, index = this.len - 1, res = "";
while (index >= 0) {
res += '-' + current.data;
current = current.prev;
index--
}
return res.slice(1)
}
}
let dlist = new DoubleLinkList();
for (let i = 0; i < 10; i++) {
dlist.append(i)
}
dlist.remove(4)
dlist.remove(8)
dlist.insert(4, "hello")
console.log(dlist.toAfterString());
console.log(dlist.toBeforeString());
双向链表
既可以从头遍历到尾, 又可以从尾遍历到头
-
一个节点既有向前连接的引用, 也有一个向后连接的引用.
-
双向链表可以有效的解决单向链表中提到的问题.
-
双向链表有什么缺点呢?
-
每次在插入或删除某个节点时, 需要处理四个节点的引用, 而不是两个. 也就是实现起来要困难一些
-
并且相当于单向链表, 必然占用内存空间更大一些.
-
但是这些缺点和我们使用起来的方便程度相比, 是微不足道的.