栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

合并两个排序链表(C语言)

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

合并两个排序链表(C语言)

先看题,其实题目很明白:

输入两个递增排序的链表,合并这两个链表并使新链表中的节点仍然是递增排序的。

示例1:

输入:1->2->4, 1->3->4
输出:1->1->2->3->4->4

这道题有递归和非递归做法,主要学习的是递归的想法。

题目的函数:

struct ListNode *mergeTwoLists(struct ListNode *l1, struct ListNode *l2){}

法一:递归

我们以下面这个例子来看怎么做递归:

1->6->7 头指针l1

2->5->8 头指针l2

l1的值比l2小,所以l1应该排在l2后面,但是不能直接就把l1->next指向l2,因为l2和l1->next的节点的值还没比过,所以得出结论,l1的next应该指向l2或者还是l1->next。

所以我们再次调用本函数,并且写成 l1->next=mergeTwoLists(l1->next,l2);

所以现在我们就可以写出一个条件判断语句了:

 if (l1->val < l2->val)
         l1->next = mergeTwoLists(l1->next, l2);
     else
         l2->next = mergeTwoLists(l1, l2->next);

一直递归调用函数,直到l1或者l2有一个是NULL,这时候我们可以写递归出口了。如果l1是空,那么上一个l1的值其实就比l2小了,l2应该排在最后面,这时不管l2到没到链表最后也没事,l2后面的节点的值都比l1的大,那么就直接返回l2。

if (l1 == NULL || l2 == NULL)
         return l1 == NULL ? l2 : l1;

把递归出口放在函数开头。

但是我们这个函数返回的是指针类型,最后总归要return一个指针,return谁?

看看我们什么时候调用的:l1->next = mergeTwoLists(l1->next, l2);

如果是这个情况,mergeTwoLists(l1->next, l2)应该返回谁?我们之前分析的是l1的next应该指向l2或者还是l1->next。其实就是指向对应val小的那一个,所以我们要比较l1->next和l2的val的值谁小,而在递归函数中,l1->next被传值赋成了l1,所以就是比较下一个递归函数中l1,l2谁的val小,谁小就return谁。

return l1->val < l2->val ? l1 : l2;

合并我们上面给出的代码:

struct ListNode *mergeTwoLists(struct ListNode *l1, struct ListNode *l2) {
	 if (l1 == NULL || l2 == NULL)
		 return l1 == NULL ? l2 : l1;
	 if (l1->val < l2->val)
		 l1->next = mergeTwoLists(l1->next, l2);
	 else
		 l2->next = mergeTwoLists(l1, l2->next);
	 return l1->val < l2->val ? l1 : l2;
 }

步骤图:(从左往右看)

 

 

 法二:双指针

 简单提一下双指针,就是l1和l2不停比较然后迭代,这个不详细说了,详情去看网上的题解吧。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/867643.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号