• 4 合并两个排序的链表


    0 引言

    题目描述:输入两个递增排序的链表,合并这两个链表并使新链表中的结点仍然是按照递增排序的。链表结点定义如下。

    struct ListNode
    {
      int val;
      ListNode* next;    
    }

    1 抽象问题具体化

    举例1:
    链表1:1->3->5->7
    链表1:2->4->6->8
    合并链表:1->2->3->4->5->6->7->8
    
    举例2:
    链表1:NULL
    链表2:1->2->3->4
    合并链表:1->2->3->4
    
    举例3:
    链表1:NULL
    链表2:NULL
    合并链表:NULL

    2 具体问题抽象化

    (1)定义接口:

    ListNode* Merge(ListNode* p, ListNode* q);

    (2)操作流程

    1)输入两个链表,并定义合并链表头结点,保留当前比较小的链表头结点作为返回结点,合并链表的尾节点指向较小的结点

    2)开始循环操作:定义循环结束条件,某个链表活动结点指向了NULL,此时跳出循环,而且合并链表尾节点将等于另一个链表活动结点。

    3)循环中的操作:当前活动结点等于两个活动结点中的一个,判断两个活动结点哪个小(或者等于),合并结点尾指针指向大的那个结点,并将另一个结点向前移动一个位置。

    4)返回合并链表头结点

    (3)流程图

     3 demo

        ListNode* Merge(ListNode* pHead1, ListNode* pHead2)
        {
            if(pHead1 == NULL)
                return pHead2;
            if(pHead2 == NULL)
                return pHead1;
            ListNode* r = NULL;
            if(pHead1->val <= pHead2->val)
                r = pHead1;        
            else
                r = pHead2;            
            ListNode* tail = r;  // 合并链表活动尾节点
            while(!(pHead1 == NULL || pHead2 == NULL)){
                ListNode* next;
                if(pHead1->val <= pHead2->val){
                    next = pHead1->next;
                    tail->next = pHead2;
                    pHead1 = next;
                    tail = tail -> next;
                }
                else{
                    next = pHead2->next;
                    tail->next = pHead1;
                    pHead2 = next;
                    tail = tail -> next;
                }    
            }
            return r;
      }

    4 代码优化

    (1)分析:上述代码中合并列表的尾结点tail与两个活动结点中的一个相等,导致在延长合并链表时(tail->next = pHead2),出现了断裂,不得不保存next,增加了内存开支。可以通过优化代码避免这一点。写法如下。

    ListNode* Merge(ListNode* pHead1, ListNode* pHead2){       
         if(pHead1 == NULL)
                return pHead2;
            if(pHead2 == NULL)
                return pHead1;
            ListNode* r = NULL;
            if(pHead1->val <= pHead2->val){
                r = pHead1;
                pHead1 = pHead1->next; // 改动1
            }                    
            else{
                r = pHead2;
                pHead2 = pHead2->next;  // 改动2
            }                        
            ListNode* tail = r;  // 合并链表活动尾节点
            while(!(pHead1 == NULL || pHead2 == NULL)){
           // ListNode* next; // 改动3
    if(pHead1->val <= pHead2->val){ tail->next = pHead1; pHead1 = pHead1->next; // 改动4 tail = tail -> next; } else{ tail->next = pHead2; pHead2 = pHead2->next; // 改动5 tail = tail -> next; } } tail ->next = pHead1?pHead1:pHead2; // 改动6 return r; }
  • 相关阅读:
    MOOK学习
    寒假学习计划
    三位影响深刻的老师
    软工第三次作业-结对作业
    2018软工实践第二次作业
    2018软工实践第一次作业
    简单的自我介绍
    福大软工1816 · 第一次作业
    课程作业八
    课程作业七
  • 原文地址:https://www.cnblogs.com/ghjnwk/p/9975859.html
Copyright © 2020-2023  润新知