📅  最后修改于: 2023-12-03 14:56:19.752000             🧑  作者: Mango
双向链表是一个常见的数据结构,它每个节点都有向前和向后两个指针,可以实现双向遍历。而链表的反转则是一个经典的算法问题,本文将介绍一种用于反转双向链表的 Javascript 程序。
我们先来定义一个双向链表的节点类:
class ListNode {
constructor(val, prev = null, next = null) {
this.val = val
this.prev = prev
this.next = next
}
}
其中 val
表示节点的值,prev
表示指向前一个节点的指针,next
表示指向下一个节点的指针。这个节点类可以很方便地创建一个双向链表。
双向链表反转需要修改每个节点的 prev
和 next
指针,让它们各自指向相反的方向。下面是一种基于迭代的算法实现:
function reverseList(head) {
let prev = null
let curr = head
while (curr) {
let next = curr.next
curr.next = prev
curr.prev = next
prev = curr
curr = next
}
return prev
}
首先定义两个指针 prev
和 curr
,分别表示前一个节点和当前节点。然后用一个 while 循环遍历整个链表,在每次循环中,将 curr
的 next
指针指向 prev
,prev
的 prev
指针指向 curr
的 next
,然后将指针向后移动。最后返回反转后的链表头。
这个算法的时间复杂度为 O(n),空间复杂度为 O(1)。
我们可以用下面的代码片段来测试这个算法:
const node1 = new ListNode(1)
const node2 = new ListNode(2)
const node3 = new ListNode(3)
node1.next = node2
node2.prev = node1
node2.next = node3
node3.prev = node2
console.log(node1)
console.log(reverseList(node1))
这里创建了一个由三个节点组成的链表,然后打印出原始链表和反转后的链表。执行结果如下:
ListNode {
val: 1,
prev: null,
next: ListNode { val: 2, prev: [Circular], next: [ListNode] }
}
ListNode {
val: 3,
prev: ListNode { val: 2, prev: [Circular], next: [ListNode] },
next: ListNode { val: 1, prev: [ListNode], next: null }
}
我们可以看到,反转后的链表的头结点是原来的尾节点,尾节点是原来的头结点,而其他节点也按照相反的方向进行了连接。
本文介绍了一种用于反转双向链表的 Javascript 程序。这个算法的时间复杂度为 O(n),空间复杂度为 O(1),可以很方便地应用到实际的问题中。