【leetcode】链表--合并有序链表

将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。

示例:

输入: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;
}

猜你喜欢

转载自blog.csdn.net/qq_41189882/article/details/102927130