链表逆置的原理
- 想要实现链表的逆置,只要反转链表中每一个节点的指向即可
- 但是如何反转就要思考一下了
- 链表中间除了最后一个节点,每一个节点的都通过当前节点
node.next
指向下一个节点
- 只有最后一个节点的下一个节点指向的是null
- 所以,就可以从最后一个节点入手
- 首先,把最后一个节点
node.next
指向倒数第二个节点
- 然后将倒数第二个节点
node.next
指向null,这个时候的链表仍然是连续的
- 但是这里有两个问题
- 如何让倒数第二个节点
node.next
指向null?
- 如何让最后一个节点
node.next
指向倒数第二个节点?
- 因为使用的是单向链表,每一个节点都认为自己是根节点,也就是说每一个节点当前节点只能查询自己之后的节点,对自己之前的节点是没有办法获取的
- 所以,这里如果直接通过遍历找到最后一个节点,然后把它的next指向null的话,那前边的节点就没办法解决了
- 我这里采用的是使用
node.next
去表示下一个节点,使用node.next.next
表示最后一个节点的next
- 让
node.next.next
指向前一个节点node
,然后让node
的next指向null
- 通过递归,递归的出口为
node.next.next
为null的节点,然后用上述方法改变指向
- 具体实现代码如下:
// 创建一个节点的类
class Node {
constructor(value) {
this.value = value
this.next = null
}
}
// 创建节点
const node1 = new Node(1)
const node2 = new Node(2)
const node3 = new Node(3)
const node4 = new Node(4)
const node5 = new Node(5)
const node6 = new Node(6)
// 将所有的节点穿成一个串,形成一个链表
node1.next = node2
node2.next = node3
node3.next = node4
node4.next = node5
node5.next = node6
const reverseLink = root => {
if (root.next.next === null) { // 当前root为倒数第二个节点
root.next.next = root // 最后一个节点指向前一个节点
return root.next // 返回最后一个节点
} else {
let result = reverseLink(root.next)
root.next.next = root // 当前节点的后一个节点的next指向当前节点
root.next = null // 让当前节点的next指向null
console.log(result)
return result
}
}
const newRoot = reverseLink(node1)
// 遍历逆置后的链表
const traverseLink = newRoot => {
if (newRoot === null) {
return
}
console.log(newRoot.value)
// 使用递归旁遍历当前链表
traverseLink(newRoot.next)
}
traverseLink(newRoot)