每日编程6之单链表反转递归版本
来源:互联网 发布:vue.js设置button隐藏 编辑:程序博客网 时间:2024/06/05 04:12
既然链表逆序输出可以用递归方法实现,单链表反转也可以采用递归思想实现。
不同的地方时,后者需要破坏原有的链表结构
不晓得采用1个指针能不能实现
先考虑用2个指针p,q分别记录原来的链表关系
初始时:p = NULL,q = head; 特殊条件为q==NULL,表示链表中没有元素,这也可以作为递归结束条件(这可以成为一种找递归结束条件的思路)
递归处理操作是:p=q;q=q->next;linkList_reverse_recur(p,q) 如果这里q==NULL,说明p为最后一个元素,p即为反转后的链表表头
核心处理操作是:q->next = p
不对
如果是递归的话,在核心处理部分开始的时候,原有的链表结构为被打乱,也就不需要用一个额外的指针记录前一个节点指针,
用1个指针p开始递归,p初始为p=head,结束应该是p->next == NULL 考虑到head==NULL的特殊情况,这也应该放到递归结束条件里去
核心处理为:p->next->next = p; 因为虽然递归的因子是p,但实际上处理的是p->next的后继指针,所以p->next == NULL 为结束条件 当然为了保证逆序,该处理 要放在递归操作之后
递归操作:linkList_reverse_recur(p->next)
关于递归函数的返回值,这个其实没关系,因为我只要保证最后一层的返回结果就行了。但因为递归还要进行出栈,所以这里不能return,因此必须增加一个参数来保存反转后表头的位置
执行程序的时候出现无限循环,原来是第一个元素没有处理,导致第一个元素和第二个元素徐成一个链循环,不停的打印8和9
要对一个元素和最后一个处理的第一个元素进行单独处理,那么如何判断一个元素是那个元素,只能通过指针判断,因此必须加一个参数来说明原来表头指针oldhead,通过判断p==oldhead来进行处理
核心代码:
int linkList_reverse_recur(struct node *oldhead,struct node* &newhead,struct node *p) //三个参数是必须的,见前面的分析
{
if(p == NULL) //链表为空的特殊情况处理,仅在第一次递归时判断一次,后续的递归不可能出现这种情况,切记这一点
return 0;
if(p->next != NULL)
{
linkList_reverse_recur(oldhead,newhead,p->next);
p->next->next = p; //核心处理,此时顺序的链表结构尚未被破坏
}
else
{
newhead = p;
}
if(p == oldhead) //放在最后,单独处理第一个元素
p->next = NULL;
}
OVER!!!
- 每日编程6之单链表反转递归版本
- 每日编程22之递归实现栈的反转
- 每日编程4之单链表反转
- 每日编程7之快速排序非递归版本
- 每日编程9之二叉树的先序遍历递归版本
- 每日编程10之二叉树的先序遍历的非递归版本
- 单链表的反转(非递归与递归版本)
- 不开辟新空间反转单链表(递归版本)
- 每日编程3之快速排序随机化版本
- 单链表递归反转
- 每日编程5之逆序输出单链表
- 单链表反转(非递归)
- 单链表反转的递归方法
- 单链表的反转(递归)
- 【leetcode】通过递归反转单链表
- 反转单链表 递归与非递归
- 单链表反转(递归和非递归)
- 单链表反转:递归与非递归实现
- 读书方法分享
- myeclipse下自建user library的方法
- warning C4996: 'strcpy' was declared deprecated
- 致我们这些浮躁的程序猿
- Android常用命令操作(继续更新)
- 每日编程6之单链表反转递归版本
- C#网络编程系列三:自定义Web服务器
- 商餐网
- MySQL查询优化:连接查询排序limit(join、order by、limit语句)
- 50多个开源PDF阅读编辑工具汇总
- Extjs4HtmlEditor图片上传插件
- 服务器程序中如何设计retry功能
- Book
- java List合并相同的项问题