21. Merge Two Sorted Lists题目和答案详解

1 题目简述

Merge two sorted linked lists and return it as a newlist. The new list should be made by splicing together the nodes of the first two lists.

合并两个已排序的链表并将其作为一个新列表返回。新列表应该通过拼接前两个列表的节点来完成。

Example:

Input: 1->2->4, 1->3->4

Output: 1->1->2->3->4->4

2 答案详解

(1) 解决思想

  本次解答采用C++编写,C++相对于C语言的一个重要的特点是:面向对象编程(OOP),故我们采用类的方法来实现所述要求。

  为了让读者能简易地理解作者的思路,故后面会以举例子的形式来阐述。两个有序链表的状态有5种情况,称这两个链表为first和second:

  1.first链表为空,second链表不为空。

  2.first链表不为空,second链表为空。

  3.两个链表均为空。

  4.两个链表均不为空,且first链表的首节点元素值<second链表的首节点元素值

  5.两个链表均不为空,且first链表的首节点元素值>=second链表的首节点元素值

针对以上5种情况进行相应的处理:

  1.针对情况1,返回first链表。

  2.针对情况2,返回second链表。

  3.针对情况3,返回first链表(为空)。

  4.针对情况4,不做操作。

  5.针对情况5,将first链表和second链表互换,使之变为情况4。

  现在,针对情况4和情况5来进行举例来详细说明。设有两个有序链表分别为:2->4->7,1->3->5->6,将其分别赋给first和second。首先做判断,由于两个链表均不为空,且first链表的首节点元素值>=second链表的首节点元素值,故交换两个链表,此时first链表变为1->3->5->6,而second链表变为2->4->7。

  然后,应知道目的是合并两个有序链表,而不是新建一个合并后的链表,即改变两个链表的节点的后继指向,而不开辟新的空间来容纳合并后的链表。接下来,由于要访问两个链表,故建立两个节点指针:temp指针指向first链表首节点,comp指针指向second链表首节点。

  之后,为了使得temp指向的节点值始终<comp指向的节点值,故进行分步操作进行说明:

  1.将temp->next(值为3)与comp(值为2)进行比较,发现3>2,故将temp->next与comp进行交换后,first链表变为:1->2->4->7,而comp此时指向的链表变为:3->5->6。而后将temp赋值为temp->next,值为2。

  2.将temp->next(值为4)与comp(值为3)进行比较,发现4>3,故将temp->next与comp进行交换后,first链表变为:1->2->3->5->6,而comp此时指向的链表变为:4->7。而后将temp赋值为temp->next,值为3。

  3.将temp->next(值为5)与comp(值为4)进行比较,发现5>4,故将temp->next与comp进行交换后,first链表变为:1->2->3->4->7,而comp此时指向的链表变为:5->6。而后将temp赋值为temp->next,值为4。

  4.将temp->next(值为7)与comp(值为5)进行比较,发现7>5,故将temp->next与comp进行交换后,first链表变为:1->2->3->4->5->6,而comp此时指向的链表为:7。而后将temp赋值为temp->next,值为5。

  5.将temp->next(值为6)与comp(值为7)进行比较,发现6<7,故不进行操作,此时first链表仍为:1->2->3->4->5->6,comp指向的链表仍为:7。而后将temp赋值为temp->next,值为6。

  6.由于temp指向了first链表的最后一个节点,所以此时comp指向的链表上的所有节点值均>=first最后一个节点值,故可直接将temp->next赋值为comp。此时first链表变为:1->2->3->4->5->6->7。

  最后,返回first链表。

(2) 设计程序

  所设计的程序采用类模板实现,程序如下:

#include <iostream>

using std::cout;
using std::endl;

struct ListNode {
    int val;
    ListNode* next;
    ListNode(int x):val(x),next(NULL) {}
};

template<class T>
class Solution
{
private:
    T first_;
    T second_;
public:
    Solution(const T& first,const T& second):first_(first),second_(second) {}
    T& MerTwoSorLists();
};

template<class T>
T& Solution<T>::MerTwoSorLists()
{
    T temp(NULL);
    T comp(NULL);
    T swap(NULL);
    if(first_ == NULL and second_ != NULL) {
        return second_;//如果第一个链表为空,而第二个链表不为空,则返回第二个链表
    } else if(first_ != NULL and second_ == NULL) {
        return first_;//如果第一个链表不为空,而第二个链表为空,则返回第一个链表
    } else if(first_ == NULL and second_ == NULL) {
        return first_;//如果两个链表都为空,则返回第一个链表
    } else if(first_ -> val > second_ -> val) {
        swap = first_;
        first_ = second_;
        second_ = swap;//如果第一个链表的首个元素大于第二个链表的首个元素,则交换两个链表
    }
    temp = first_;
    comp = second_;//temp和comp用于遍历两个链表
     /*若两个链表不为空,则合并两个链表,此过程没有创建新的链表,而是改变两个链表中的节点的指向*/
    while(temp != NULL or comp != NULL) {//遍历条件:均未遍历到两个链表的末端
        if(temp->next == NULL) {
            temp->next = comp;
            return first_;//如果遍历到temp最后一个节点,则将temp的下一个节点赋值为comp,因为comp指向的节点元素值始终>=temp指向的节点元素值
        } else if(temp->next->val < comp->val) {
            temp = temp->next;//如果此时temp下一个节点的元素< comp节点的元素,则temp指向temp下一个节点
        } else {
            swap = temp->next;
            temp->next = comp;
            comp = swap;
            temp = temp->next;//如果此时temp下一个节点的元素>= comp节点的元素,则交换temp->next和comp,并让temp指向temp下一个节点。目的:为了使temp节点的元素始终小于comp节点的元素
        }
    }
}
template<class T>
void Show(T pnode)
{
    while(pnode != NULL) {
        cout << pnode->val ;
        if(pnode->next != NULL) {
            cout << "->";
        }
        pnode = pnode->next;
    }
    cout << endl;
}

int main()
{
    ListNode n11(1);
    ListNode n12(3);
    ListNode n13(5);
    ListNode n14(6);
    n11.next = &n12;
    n12.next = &n13;
    n13.next = &n14;
    ListNode n21(2);
    ListNode n22(4);
    ListNode n23(7);
    n21.next = &n22;
    n22.next = &n23;
    cout << "The first list:";
    Show(&n21);
    cout << "The second list:";
    Show(&n11);
    Solution<ListNode*> sol(&n21,&n11);
    ListNode* res = sol.MerTwoSorLists();
    cout << "After the merger:";
    Show(res);
}
程序运行结果为:

The first list:2->4->7
The second list:1->3->5->6

After the merger:1->2->3->4->5->6->7




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值