合并两个排序的链表


题目:输入两个递增排序的链表,合并这两个链表并使新链表中的结点仍然是按照递增排序的。例如下图中的链表1和链表2,则合并之后的升序链表如链表3所示。

 

链表结点定义如下:

struct  ListNode
{
     int  m_nValue;
     ListNode *m_pNext;
};

 

注:链表1和链表2是两个递增排序的链表,合并这两个链表得到升序链表为链表3.

首先分析合并两个链表的过程。我们的分析从合并两个链表的头结点开始。链表1的头结点的值小于链表2的头结点的值,因此链表1的头结点将是合并后链表的头结点。如下图所示。

  • 链表1的头结点的值小于链表2的头结点的值,因此链表1的头结点是合并后链表的头结点。
  • 在剩余的结点中,链表2的头结点的值小于链表1的头结点的值,因此链表2的头结点是剩余结点的头结点,把这个结点和之前已经合并好的链表的尾结点链接起来。

继续合并两个链表中剩余的结点(图中虚线框所示)。在两个链表中剩下的结点依然是排序的,因此合并这两个链表的步骤和前面的步骤是一样的。我们还是比较两个头结点的值。此时链表2的头结点的值小于链表1的头结点的值,因此链表2的头结点的值将是合并剩余结点得到的链表的头结点。我们把这个结点和前面合并链表时得到的链表的尾结点(值为1的结点)链接起来,如图所示。

当我们得到两个链表中值较小的头结点并把它连接到已经合并的链表之后,两个链表剩余的结点依然是排序的,因此合并的步骤和之前的步骤是一样的。这就是典型的递归的过程,可以定义递归函数来完成者以合并过程。

每当代码试图访问空指针指向的内存时程序就会崩溃,从而导致鲁棒性问题。在本题中,当第一个链表是空链表,也就是它的头结点是一个空指针时,那么把它和第二个链表合并,显然合并的结果是第二个链表。同样,当输入的第二个链表的头结点是空指针时,我们把它和第一个链表合并得到的结果就是第一个链表。如果两个链表都是空链表,合并的结果是得到一个空链表。

实现代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
ListNode* Merge(ListNode* pHead1, ListNode* pHead2)
{
     if (pHead1 == NULL)
         return  pHead2;
     else  if (pHead2 == NULL)
         return  pHead1;
 
     ListNode* pMergedHead = NULL;
 
     if (pHead1->m_nValue < pHead2->m_nValue)
     {
         pMergedHead = pHead1;
         pMergedHead->m_pNext = Merge(pHead1->m_pNext, pHead2);
     }
     else
     {
         pMergedHead = pHead2;
         pMergedHead->m_pNext = Merge(pHead1, pHead2->m_pNext);
     }
 
     return  pMergedHead;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值