递归反转
本文介绍递归反转单链表,和之前的循环遍历反转单链表方式略有不同,递归的方式要写出推到递归公式。并且在递归的同时修改指针的指向。
先定义Node节点
1 | class Node |
Node节点构成的链表如下图
基本思路是实现recursive_reverse函数
1 | Node* recursive_reverse(Node* p){ |
上述代码最终会将链表的尾节点返回。但是我们没有完成链表的逆转,需要改变链表节点Node的next指针。
假设有两个节点
node1节点为p节点p->next
指向的就是node2节点p->next->next
指向的就是末尾的空指针。
所以当有两个节点的时候我们可以如下操作完成p和p->next
两个节点指向的修改,也就是node1和node2两个节点的修改。
我们将p->next->next = p->next
就是将node2的next指向了node1.
我们将p->next = nullptr
就是将node1->next
指向了空地址。所以node1此时变为尾节点。
而之前的递归保证了最后返回的是node2节点,此时node2节点就作为头节点,从而完成了逆转。
图解为下图
这是两个节点的情况,如果是三个节点呢,那就依次类推,依次完成node3->next
指向node2,node2->next
指向node1,node1->next
指向空地址。
所以n>=2的情况都是和两个节点类似的,那么我们补全recursive_reverse函数
1 | Node *recursive_reverse(Node *p) |
接下来我们实现一个创建链表的函数用来测试
1 | Node *createList() |
然后实现销毁链表回收内存的函数
1 | void delocateList(Node *p) |
然后实现打印节点的函数
1 | void printList(Node *p) |
最后我们在main函数中测试
1 | auto list = createList(); |
程序输出如下
1 | 1 -> 2 -> 3 -> nullptr |
可以看到链表被逆转了。
源码链接https://gitee.com/secondtonone1/algorithms
我的公众号,谢谢关注