返回
从单向到双向:揭秘双向链表的奥秘
前端
2023-10-06 12:38:22
在探索数据结构的奇妙世界时,我们早已结识了单向链表,它如同一条单行道,信息只能从头到尾或从尾到头流动。而今天,让我们踏上双向链表的征程,揭开它的独特魅力!
双向链表:双向通行的信息通道
双向链表与单向链表有着本质的区别,它是一种双向通行的信息通道。在双向链表中,每个节点除了指向下一个节点的指针外,还多了一个指向前一个节点 的指针,如同一条双车道公路,信息可以自由地从两端穿梭。
双向链表的优势:灵活性与效率
双向链表的双向通行性赋予了它独特的优势:
- 高效查找: 双向指针允许从链表的任意位置快速查找元素,无论正向还是反向。
- 便捷删除: 删除一个节点时,无需遍历整个链表,只需修改其前后指针即可。
- 灵活插入: 在双向链表中插入一个新节点非常方便,因为我们可以从任一端进行插入。
双向链表的应用场景
双向链表在实际开发中有着广泛的应用:
- 浏览器历史记录: 浏览器通过双向链表来记录用户的历史记录,用户可以轻松地前进或后退浏览。
- 文本编辑器: 文本编辑器使用双向链表来存储文本,方便插入、删除和移动文本。
- 虚拟内存管理: 操作系统使用双向链表来管理虚拟内存页面,实现高效的内存分配和释放。
实现双向链表:用代码构建
在 JavaScript 中,实现双向链表非常简单:
class Node {
constructor(data) {
this.data = data;
this.next = null;
this.prev = null;
}
}
class DoublyLinkedList {
constructor() {
this.head = null;
this.tail = null;
this.size = 0;
}
// 添加节点到链表尾部
append(data) {
let newNode = new Node(data);
if (this.head === null) {
this.head = newNode;
this.tail = newNode;
} else {
this.tail.next = newNode;
newNode.prev = this.tail;
this.tail = newNode;
}
this.size++;
}
// 从链表中删除一个节点
delete(node) {
if (node === this.head) {
this.head = node.next;
if (this.head !== null) {
this.head.prev = null;
} else {
this.tail = null;
}
} else if (node === this.tail) {
this.tail = node.prev;
if (this.tail !== null) {
this.tail.next = null;
} else {
this.head = null;
}
} else {
node.prev.next = node.next;
node.next.prev = node.prev;
}
this.size--;
}
// 从链表中查找一个节点
find(data) {
let curr = this.head;
while (curr !== null) {
if (curr.data === data) {
return curr;
}
curr = curr.next;
}
return null;
}
}
拓展阅读: