Preface
The above briefly introduced the data structure-using JS to realize the linked list-singly linked list ; this article appears as a sequel. The realization of a doubly linked list further deepens some concepts and realization of the linked list.
The coding part is implemented by javascript. complete code link
Linked list
A doubly linked list is also called a double-linked list, which is a kind of linked list. Each data node has two pointers , which point to the direct successor and the direct predecessor respectively. Therefore, starting from any node in the doubly linked list, you can easily access its predecessor and successor nodes. Generally, we construct a two-way circular linked list . 【Baidu Encyclopedia】
Linked list features
- Use a set of arbitrary memory space to store data elements (the memory space here can be continuous or discontinuous)
- Each node (node) consists of the data itself, a pointer to the previous node , and a pointer to the subsequent node
- Access to the entire linked list must start from the head pointer, which points to the first node. tail pointer ends, and the tail pointer points to the last node.
There are no pointers in JS, and the pointers of the above nodes are just borrowed concepts from the C language.
Linked list complexity
time complexity
Access | Search | Insertion | Deletion |
---|---|---|---|
O(n) | O(n) | O(1) | O(1) |
Space complexity
O(n)
Basic operation realization
Node structure
// 与单链表区别在于多了之前节点的指向
class DoublyLinkedListNode {
constructor(value, next = null, previous = null) {
this.value = value;
this.next = next;
this.previous = previous;
}
}
Linked list initialization
class DoublyLinkedList {
constructor() {
this.head = null;
this.tail = null; //多了尾部
}
}
Add insert (head and tail)
// 添加致头部
prepend(value) {
// 节点添加至头部
const newNode = new DoublyLinkedListNode(value, this.head);
// 如果有头部节点,那么设置为头部节点先前(previous)节点的引用
// 将头部节点设置为新节点
if (this.head) {
this.head.previous = newNode;
}
this.head = newNode;
// 如果没有尾部节点,把新节点设置为尾部节点.
if (!this.tail) {
this.tail = newNode;
}
return this;
}
// 添加致尾部
append(value) {
const newNode = new DoublyLinkedListNode(value);
// 同样判断 如果没有头部节点,那么将新节点设置为头部节点。
// 同时也是尾部节点
if (!this.head) {
this.head = newNode;
this.tail = newNode;
return this;
}
// 如果存在头部节点(当然也存在尾部节点)
// 将头部节点添加至链表的尾部
this.tail.next = newNode;
// 转换思考一下,当前新节点上一个个节点(previous)也就是当前this指向的尾部
newNode.previous = this.tail;
// 将新节点设置为链表的尾部
this.tail = newNode;
return this;
}
delete
For the reading experience, some non-critical codes are omitted here, and you can go to the warehouse to check it. A link will be posted later.
delete(value) {
if (!this.head) {
return null;
}
let deletedNode = null;
let currentNode = this.head;
while (currentNode) {
if (currentNode.value === value) { // 仓库引入了一个比对js.逻辑很简单
deletedNode = currentNode;
// 想想其实就是处理3种情况
//1. 如果删除的节点是头部节点 需要做什么操作
//2. 如果删除的节点是尾部节点 需要坐什么操作
//3. 如果不是头部和尾部而是中间节点 需要做什么操作
if (deletedNode === this.head) {
// 如果删除的节点是头部节点
// 那么将头设置到第二个节点,该节点将成为新头
// 设置心头的previous为null
this.head = deletedNode.next;
if (this.head) {
this.head.previous = null;
}
if (deletedNode === this.tail) {
this.tail = null;
}
} else if (deletedNode === this.tail) {
// 如果删除是尾部节点,将tail设置为倒数第二个节点,这将成为新的tail
this.tail = deletedNode.previous;
this.tail.next = null;
} else {
// 如果要删除中间节点
const previousNode = deletedNode.previous;
const nextNode = deletedNode.next;
previousNode.next = nextNode;
nextNode.previous = previousNode;
}
}
currentNode = currentNode.next;
}
return deletedNode;
}
Traversing the linked list
The coding implementation part is reflected in the deletion and can be extracted by yourself.
// 思路简单来说就是value值比对
while(){
// 正向遍历,如果当前没有依次找next 直到尾部
// 反之 如果没有依次previous 直到头部。
}
Concluding remarks
To make a simple summary, a simple understanding of the structure of a doubly linked list is that a node contains the current value, the previous, and the next. Then the initialization is head and tail one by one. Then perform additions, deletions, and modifications to this infrastructure.
After slowly understanding, it will feel very simple.
Finally, don't forget to make more contact in the actual scene.
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。