链表中的递归
什么是递归呢?函数在运行时调用自己,这个函数就叫递归函数,调用的过程叫做递归。比如定义函数f(x)=x+f(x-1)
递归的三个要点:
-
终止条件,递归应该在什么条件终止?
-
返回值,当前应该给上一级返回什么?
-
递归方法,在这一级递归中,应该完成什么任务?
例1:
将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的,例如:
输入:1->2->4, 1->3->4
输出:1->1->2->3->4->4
分析一下:
终止条件 当两个链表中有一个链表为NULL
则直接返回另外一个链表
返回值 返回给上一级一个排好序的链表
递归方法 判断 l1
,l2
头节点的大小,然后将较小的next
指向其余节点的合并结果
代码如下:
struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2){
if (!l1)//终止条件
return l2;
if (!l2)
return l1;
if (l1->val < l2->val){
l1->next = mergeTwoLists(l1->next, l2);//递归方法
return l1;//返回值
}
else{
l2->next = mergeTwoLists(l1, l2->next);
return l2;
}
}
我们用刚才的方法分析下面的问题,三个要点在注释中。
例2:
给定一个偶数项链表,两两交换其中相邻的节点,并返回交换后的链表。这里的head是指向第一个结点的指针。
struct ListNode* swapPairs(struct ListNode* head){
struct ListNode*p=NULL;
//终止条件
if((head==NULL) || (head->next==NULL)){
return head;
}else{
//单次过程
p=head->next;
head->next = p->next;
p->next=head;
head=p; //记住是head=p
//递归函数
head->next->next=swapPairs(head->next->next);
return head;
}
}
例3:
给定一个排序链表,删除所有重复的元素,使得每个元素只出现一次。
struct ListNode* deleteDuplicates(struct ListNode* head){
//终止条件
if((head==NULL) || (head->next==NULL)){
return head;
}
//递归方法
head->next=deleteDuplicates(head->next);
//单次过程
if(head->val== head->next->val){
head=head->next;
}
return head;
}
总结:
这学期开始学数据结构,在leetcode刷了一些有关链表的题,遇见了几道关于递归的题,自己开始也是用的一般方法,看了题解用递归十分感觉巧妙。
有关递归的题很多,在链表,二叉树中有很多应用实例,也可以用来解决汉诺塔,斐波那契数列等问题。但万变不离其宗,找出递归的三个重要点:终止条件,返回值,递归方法,相信问题便会迎刃而解。
学习之路路途遥远曲折,共勉!