返回
JavaScript 数据结构之链表,解剖之美
前端
2024-02-13 19:26:02
链表的组成与特点
链表由一系列称为节点(Node)的元素组成,每个节点包含两个部分:
- 数据域:存储实际的数据值。
- 指针域:存储指向下一个节点的引用。
链表的第一个节点称为头节点(Head),它指向链表中的第一个数据节点,而最后一个节点称为尾节点(Tail),它的指针域为空,表示该节点之后没有更多的节点。
链表具有以下几个特点:
- 链表是一种动态数据结构,这意味着它的大小可以根据需要增长或缩小。
- 链表中的元素可以随机访问,但需要从头节点开始逐个遍历才能找到目标元素。
- 链表中的元素可以轻松插入或删除,而不需要移动其他元素。
链表的实现
在 JavaScript 中,我们可以使用对象或数组来实现链表。
使用对象实现链表
class Node {
constructor(data) {
this.data = data;
this.next = null;
}
}
class LinkedList {
constructor() {
this.head = null;
this.tail = null;
this.length = 0;
}
// 添加元素到链表尾部
append(data) {
const newNode = new Node(data);
if (this.length === 0) {
this.head = newNode;
this.tail = newNode;
} else {
this.tail.next = newNode;
this.tail = newNode;
}
this.length++;
}
// 从链表头部移除元素
removeFirst() {
if (this.length === 0) {
return null;
}
const removedNode = this.head;
this.head = this.head.next;
if (this.length === 1) {
this.tail = null;
}
this.length--;
return removedNode.data;
}
// 从链表中查找元素
find(data) {
let currentNode = this.head;
while (currentNode !== null) {
if (currentNode.data === data) {
return currentNode;
}
currentNode = currentNode.next;
}
return null;
}
}
使用数组实现链表
class Node {
constructor(data) {
this.data = data;
this.next = null;
}
}
class LinkedList {
constructor() {
this.head = null;
this.tail = null;
this.length = 0;
}
// 添加元素到链表尾部
append(data) {
const newNode = new Node(data);
if (this.length === 0) {
this.head = newNode;
this.tail = newNode;
} else {
this.tail.next = newNode;
this.tail = newNode;
}
this.length++;
}
// 从链表头部移除元素
removeFirst() {
if (this.length === 0) {
return null;
}
const removedNode = this.head;
this.head = this.head.next;
if (this.length === 1) {
this.tail = null;
}
this.length--;
return removedNode.data;
}
// 从链表中查找元素
find(data) {
let currentNode = this.head;
while (currentNode !== null) {
if (currentNode.data === data) {
return currentNode;
}
currentNode = currentNode.next;
}
return null;
}
}
// 使用数组实现链表
class LinkedListArray {
constructor() {
this.data = [];
this.length = 0;
}
// 添加元素到链表尾部
append(data) {
this.data.push(data);
this.length++;
}
// 从链表头部移除元素
removeFirst() {
if (this.length === 0) {
return null;
}
const removedData = this.data.shift();
this.length--;
return removedData;
}
// 从链表中查找元素
find(data) {
const index = this.data.indexOf(data);
if (index === -1) {
return null;
}
return this.data[index];
}
}
链表的应用
链表在前端开发中有很多应用场景,例如:
- 存储需要频繁增删改查的数据集合,例如购物车、播放列表等。
- 实现栈和队列等数据结构。
- 实现树和图等复杂数据结构。
- 在虚拟 DOM 中,链表可以用来表示 DOM 树的结构。
链表的优缺点
链表具有以下优点:
- 插入和删除元素非常高效,不需要移动其他元素。
- 链表可以动态增长或缩小,不需要预先分配内存空间。
链表也有一些缺点:
- 链表中的元素不能随机访问,需要从头节点开始逐个遍历才能找到目标元素。
- 链表中的元素存储分散,可能会导致内存碎片。
总结
链表是 JavaScript 中一种重要的数据结构,它具有插入、删除和查找数据高效、存储空间动态分配的特点。在前端开发中,链表经常被用来存储需要频繁增删改查的数据集合、实现栈和队列等数据结构以及在虚拟 DOM 中表示 DOM 树的结构。希望本文能够帮助您更好地理解和使用链表。