c++实现---合并两个排序的链表

输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则
方法一:递归版本
代码

class Solution {
public:
    ListNode* Merge(ListNode* pHead1, ListNode* pHead2)
    {
        if(!pHead1){
            return pHead2;//如果其中一个为空,则返回另一个,两个都为空直接返回nullptr
        }
        if(!pHead2){
            return pHead1;
        }
        if(pHead1->val<=pHead2->val){//每次取最小的作为选择节点插入merge
            pHead1->next=Merge(pHead1->next,pHead2);
            return pHead1;
        }else{
            pHead2->next=Merge(pHead1, pHead2->next);
            return pHead2;
        }
    }
};

时间复杂度:O(m+n)
空间复杂度:O(m+n),每一次递归,递归栈都会保存一个变量,最差情况会保存(m+n)个变量
方法二:使用迭代,比递归更省空间
初始化:定义cur指向新链表的头结点
思路:
1.如果l1指向的结点值小于等于l2指向的结点值,则将l1指向的结点值链接到cur的next指针,然后l1指向下一个结点值
2.否则,让l2指向下一个结点值
3.循环步骤1,2,直到l1或者l2为nullptr
4.将l1或者l2剩下的部分链接到cur的后面
技巧
一般创建单链表,都会设一个虚拟头结点,也叫哨兵,因为这样每一个结点都有一个前驱结点。
注意:一定要对空链表处理,不处理可能导致空指针异常
代码

class Solution {
public:
    ListNode* Merge(ListNode* pHead1, ListNode* pHead2)
    {
        if(!pHead1){
            return pHead2;//如果其中一个为空,则返回另一个,两个都为空直接返回nullptr
        }
        if(!pHead2){
            return pHead1;
        }
        ListNode *vHead=new ListNode(-1);//虚拟头结点,类似与哨兵,记录头节点位置
        ListNode *cur=vHead;//初始化和vHead一样,在迭代的过程改变
        while(pHead1&&pHead2){
            //当两个链表的长度都满足条件
            if(pHead1->val<=pHead2->val){
                cur->next=pHead1;
                pHead1=pHead1->next;
            }else{
                cur->next=pHead2;
                pHead2=pHead2->next;
            }
            cur=cur->next;//注意:每判断完一个结点cur指针要后移
        }
        cur->next=pHead1?pHead1:pHead2;//将两个链表中剩下的那个链接到cur->next
        return vHead->next;//返回虚拟头结点的下一个
    }
};

时间复杂度:O(m+n),m,n分别为两个单链表的长度
空间复杂度:O(1)

猜你喜欢

转载自blog.csdn.net/Fizz6018/article/details/106845224
今日推荐