将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
示例:
输入:1->2->4, 1->3->4
输出:1->1->2->3->4->4
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/merge-two-sorted-lists
注:本文方法都是leetcode里C语言题解。
方法一:递归
struct ListNode* mergeTwoLists(struct ListNode* l1, struct 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(l1,l2->next);
return l2;
}
}
方法二:创建新链表,遍历插入。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
/*思路:
创建一个新结点指针,挑选l1和L2中的小者链入,和迭代法相同
目前已知的解法:
1 递归法
2 迭代法
3 头插法,遍历其中一个链表并入另一个链表
*/
struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2){
if(l1 == NULL) return l2;
if(l2 == NULL) return l1;
if(l1==NULL &&l2==NULL) return NULL;
struct ListNode *rr,*result,*result2 = l1->val<=l2->val?l1:l2;
result=result2;
while(l1&&l2) {
if(l1 && l1->val<=l2->val){
rr = l1;
l1=l1->next;
} else if(l2 && l2->val <= l1->val){
rr = l2;
l2=l2->next;
}
if (result2 != l1 && result2 !=l2){
result->next = rr;
result=result->next;
}
}
result->next = l1?l1:l2;
return result2;
}
方法三:
遍历l2,插入l1对应的位置。
要为l1创建一个虚拟头结点,这样如果l2的最小值小于l1的最小值就可以头插了。
l1链表 : l1 在左 , p1 在右 , l1从虚拟头结点开始, p1紧跟其后。
l2链表 : l2 在左 , p2 在右 , l2从第一个结点开始, p2紧跟其后。
每次比较 l2所指结点的值 与 p1所指结点的值 , 若满足l2 <= p1 , 则把l2 插到 p1 前面。 然后l2 与 p2 后移一位。
否则 l1 与 p1 后移一位。
struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2){
if(l1 == NULL) return l2;
if(l2 == NULL) return l1;
struct ListNode newhead, *p1, *p2;
newhead.next = l1;
l1 = &newhead;
while(l2 != NULL) {
p1 = l1->next;
p2 = l2->next;
if(p1 == NULL) {
l1->next = l2;
break;
}
if(l2->val <= p1->val) {
l2->next = l1->next;
l1->next = l2;
l2 = p2;
}
l1 = l1->next;
}
return newhead.next;
}
四、递归合并
struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2){
struct ListNode* newNode;
if(!l1)
return l2;
if(!l2)
return l1;
if(l1->val<l2->val)
{
newNode=l1;
newNode->next=mergeTwoLists(l1->next,l2);
}
else
{
newNode=l2;
newNode->next=mergeTwoLists(l1,l2->next);
}
return newNode;
}
五、非递归合并
struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2){
if(l1==NULL)
return l2;
if(l2==NULL)
return l1;
struct ListNode* newNode;
struct ListNode* tail;
if(l1->val<l2->val){
newNode=l1;
l1=l1->next;
}else{
newNode=l2;
l2=l2->next;
}
tail=newNode;
while(l1&&l2){
if(l1->val<l2->val){
tail->next=l1;
l1=l1->next;
}
else{
tail->next=l2;
l2=l2->next;
}
tail=tail->next;
}
if(l1)
tail->next=l1;
else if(l2)
tail->next=l2;
return newNode;
}