关于链表(Javascript)
链表是一种常见的数据结构,由一系列节点组成,每个节点包含数据和指向下一个节点的引用,在 JavaScript 中广泛应用于算法问题和实际开发
链表的基本操作
1. 单向链表的实现
下面是一个简单的单向链表的实现,包括节点定义和基本操作:
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
| class ListNode { constructor(value) { this.value = value; this.next = null; } }
class LinkedList { constructor() { this.head = null; }
append(value) { const newNode = new ListNode(value); if (this.head === null) { this.head = newNode; } else { let current = this.head; while (current.next !== null) { current = current.next; } current.next = newNode; } }
prepend(value) { const newNode = new ListNode(value); newNode.next = this.head; this.head = newNode; }
delete(value) { if (this.head === null) return;
if (this.head.value === value) { this.head = this.head.next; return; }
let current = this.head; while (current.next !== null) { if (current.next.value === value) { current.next = current.next.next; return; } current = current.next; } }
print() { let current = this.head; while (current !== null) { process.stdout.write(`${current.value} -> `); current = current.next; } console.log("null"); } }
const list = new LinkedList(); list.append(1); list.append(2); list.append(3); list.prepend(0); list.print(); list.delete(2); list.print();
|
2. 双向链表的实现
下面是一个简单的双向链表的实现,包括节点定义和基本操作:
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
| class DoublyListNode { constructor(value) { this.value = value; this.next = null; this.prev = null; } }
class DoublyLinkedList { constructor() { this.head = null; this.tail = null; }
append(value) { const newNode = new DoublyListNode(value); if (this.tail === null) { this.head = newNode; this.tail = newNode; } else { this.tail.next = newNode; newNode.prev = this.tail; this.tail = newNode; } }
prepend(value) { const newNode = new DoublyListNode(value); if (this.head === null) { this.head = newNode; this.tail = newNode; } else { this.head.prev = newNode; newNode.next = this.head; this.head = newNode; } }
delete(value) { if (this.head === null) return;
if (this.head.value === value) { this.head = this.head.next; if (this.head !== null) { this.head.prev = null; } else { this.tail = null; } return; }
let current = this.head; while (current !== null) { if (current.value === value) { if (current.next !== null) { current.next.prev = current.prev; } else { this.tail = current.prev; } current.prev.next = current.next; return; } current = current.next; } }
print() { let current = this.head; while (current !== null) { process.stdout.write(`${current.value} <-> `); current = current.next; } console.log("null"); } }
const dList = new DoublyLinkedList(); dList.append(1); dList.append(2); dList.append(3); dList.prepend(0); dList.print(); dList.delete(2); dList.print();
|
查找某个元素
问题描述:在链表中查找指定值的节点,并返回其位置索引。
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
|
function findElement(list, value) { let current = list.head; let index = 0;
while (current !== null) { if (current.value === value) { return index; } current = current.next; index++; }
return -1; }
const searchList = new LinkedList(); searchList.append(1); searchList.append(2); searchList.append(3); searchList.append(4);
console.log(findElement(searchList, 3)); console.log(findElement(searchList, 5));
|
2. 在指定位置插入元素
问题描述:在链表的指定位置插入新节点。
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
|
function insertAtPosition(list, position, value) { if (position < 0) { return false; }
if (position === 0) { const newNode = new ListNode(value); newNode.next = list.head; list.head = newNode; return true; }
let current = list.head; let index = 0;
while (current !== null && index < position - 1) { current = current.next; index++; }
if (index !== position - 1 && current === null) { return false; }
const newNode = new ListNode(value); newNode.next = current.next; current.next = newNode; return true; }
const insertList = new LinkedList(); insertList.append(1); insertList.append(2); insertList.append(4);
insertList.print(); insertAtPosition(insertList, 2, 3); insertList.print(); insertAtPosition(insertList, 0, 0); insertList.print();
|
3. 查找指定位置的元素
问题描述:获取链表中指定位置的元素值。
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
|
function getElementAtPosition(list, position) { if (position < 0 || list.head === null) { return undefined; }
let current = list.head; let index = 0;
while (current !== null && index < position) { current = current.next; index++; }
if (index === position && current !== null) { return current.value; }
return undefined; }
const positionList = new LinkedList(); positionList.append(10); positionList.append(20); positionList.append(30);
console.log(getElementAtPosition(positionList, 0)); console.log(getElementAtPosition(positionList, 2)); console.log(getElementAtPosition(positionList, 5));
|
4. 删除指定位置的元素
问题描述:删除链表中指定位置的节点。
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
|
function deleteAtPosition(list, position) { if (position < 0 || list.head === null) { return false; }
if (position === 0) { list.head = list.head.next; return true; }
let current = list.head; let index = 0;
while (current !== null && index < position - 1) { current = current.next; index++; }
if (index !== position - 1 || current.next === null) { return false; }
current.next = current.next.next; return true; }
const deleteList = new LinkedList(); deleteList.append(1); deleteList.append(2); deleteList.append(3); deleteList.append(4);
deleteList.print(); deleteAtPosition(deleteList, 2); deleteList.print(); deleteAtPosition(deleteList, 0); deleteList.print();
|
5. 获取链表长度
问题描述:计算链表中节点的数量。
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
|
function getListLength(list) { let current = list.head; let length = 0;
while (current !== null) { length++; current = current.next; }
return length; }
const lengthList = new LinkedList(); lengthList.append(1); lengthList.append(2); lengthList.append(3);
console.log(getListLength(lengthList)); lengthList.append(4); console.log(getListLength(lengthList));
|
其他操作
- 查找元素:根据值查找节点位置
- 指定位置插入:在特定位置插入新节点
- 指定位置获取:获取特定位置的节点值
- 指定位置删除:删除特定位置的节点
- 递归反转:使用递归方式反转链表
- 获取长度:统计链表中节点的数量
反转链表
问题描述:反转一个单向链表
- 初始化 prev 为 null(新链表的尾部)。
- current 从链表头节点开始。
- 在循环中:
- 暂存 next = current.next(避免指针丢失)。
- 将 current.next 指向 prev(反转当前指针)。
- 更新 prev = current(前移 prev)。
- 更新 current = next(前移 current)。
- 循环结束后,prev 指向原链表的尾节点(新头节点),更新 list.head = prev。
其实就是三指针原地反转

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
|
function reverseLinkedList(list) { let prev = null; let current = list.head; while (current !== null) { let next = current.next; current.next = prev; prev = current; current = next; } list.head = prev; return list; }
const rList = new LinkedList(); rList.append(1); rList.append(2); rList.append(3); rList.print(); reverseLinkedList(rList); rList.print();
|
合并两个有序链表
问题描述:合并两个有序链表,使结果链表仍然有序。
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
|
function mergeTwoLists(l1, l2) { let dummy = new ListNode(0); let current = dummy;
let p1 = l1.head; let p2 = l2.head;
while (p1 !== null && p2 !== null) { if (p1.value < p2.value) { current.next = p1; p1 = p1.next; } else { current.next = p2; p2 = p2.next; } current = current.next; }
if (p1 !== null) { current.next = p1; } if (p2 !== null) { current.next = p2; }
let mergedList = new LinkedList(); mergedList.head = dummy.next; return mergedList; }
const list1 = new LinkedList(); list1.append(1); list1.append(3); list1.append(5); const list2 = new LinkedList(); list2.append(2); list2.append(4); list2.append(6);
const mergedList = mergeTwoLists(list1, list2); mergedList.print();
|
更新中