leetcode_数据结构_链表_21合并两个有序链表(递归初步)
递归初步学习参考了以下博客:
https://lyl0724.github.io/2020/01/25/1/
本题:
https://leetcode-cn.com/problems/merge-two-sorted-lists/
方法一:哑结点,暴力
设一个哑结点为合并后链表的暂时头节点,待两个链表归并完毕后再删除,代码如下:
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode() : val(0), next(nullptr) {} * ListNode(int x) : val(x), next(nullptr) {} * ListNode(int x, ListNode *next) : val(x), next(next) {} * }; */ class Solution { public: ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) { if(!l1)return l2; if(!l2)return l1; //设立哑结点暂时作为头节点,如果不设立哑结点,直接另l1的第一个元素为头节点,若l2的第一个元素比l1的第一个元素小,则应该是l2的第一个元素为头节点,发生错误 ListNode *dummy=new ListNode(0,l1); ListNode *p1=l1,*p2=l2,*tail=dummy;//尾插法 while(p1&&p2){ if(p1->val<=p2->val){ tail->next=p1; tail=p1; p1=p1->next; }else{ tail->next=p2; tail=p2; p2=p2->next; } } if(p1)tail->next=p1; if(p2)tail->next=p2; ListNode *ans=dummy->next; delete dummy; return ans; } };
方法二:递归:
将两个有序l1,l2链表合并为一个链表,首先考虑,当l1为NULL时,返回l2,当l2为NULL时,返回l1,当两个链表都不为空时,讨论以下内容:
递归的返回条件:
所有结点合并完毕后,即某一个链表为空时
接下来讨论,当递归进行到某一级时,应该怎么做。不妨假设到第一级时,有l1,l2,以及l1,l2之后已经合并好的链表,那么,应该比较l1,l2的值,他们两个较大者应该与 已经合并好的链表 合并,然后较小者再指向新合并好的链表,比如,l1->val<l2->val,那么l1->next=merge(l1->next,l2)
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode() : val(0), next(nullptr) {} * ListNode(int x) : val(x), next(nullptr) {} * ListNode(int x, ListNode *next) : val(x), next(next) {} * }; */ class Solution { public: ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) { if(l1==NULL)return l2; if(l2==NULL)return l1; if(l1->val<=l2->val){ l1->next=mergeTwoLists(l1->next,l2); return l1; } else{ l2->next=mergeTwoLists(l2->next,l1); return l2; } } };
递归初步2见: