深究单链表合并(案例:LeetCode:21.合并两个有序链表)

目录

前言

一,案例题目分析

1.1 LeetCode 21.合并两个有序链表

1.2图画实例

1.3思路分析

1.3.1需要用到的指针

1.3.2整体思路

二,案例代码分析

2.1 某个链表为空

2.2整体循环 

2.3最后多于节点链接

三,原码

四,总结


前言

小伙伴们大家好啊!我们知道,对于链表而言,其实有时需要同数组一样,将所有元素进行有序合并,以便后续对数据进行分析。那么对于单链表而言,因为涉及到指针域 next 的问题,合并序列也将变得比较复杂。

那么具体是怎样去实现呢,接下来我们一一分析。

一,案例题目分析

这里为了大家可以更好理解,我们通过一个力扣上的案例来分析。

1.1 LeetCode 21.合并两个有序链表

那么我们看到,题目中要求将两个升序链表合并为一个链表之后,将新的升序链表返回,并且不能缺任何一个节点。

1.2图画实例

那么如下图所示,有两个链表,在合并之后,变成了一个新链表.

当然,这只是一个方面,因为我们不保证两个链表中的节点大小以及是否为空的情况,所以这只是一个正常的例子。

1.3思路分析

虽然该题可能有很多的思路,但是这里我们只提供一种相来说比较有效的一种思路。

1.3.1需要用到的指针

那么因为我们是新开辟了一个链表,所以对于新链表,因为需要新加入节点,所以就仅仅是增加节点的话,就相当于新链表的尾插操作了。那么尾插的话,就需要两个指针,一个指针不动用来记录链表,另一个指针就需要一直移动来插入节点了。

其次,因为一般情况下,我们是不动链表的头指针的,所以额外需要两个指针去移动原先两个链表的节点。

1.3.2整体思路

我们主要的思路。首先就是新建一个空链表指针,然后比较两个链表中的节点,假设链表1的当前节点的值大于链表 2 的,那么我们就将新链表的指针指向较小链表的那个节点,然后再将较小链表的指针后移一位;然后接下来就是同样的操作,直到两个链表任意一个全部移动到新链表。

此时就会退出循环了,退出之后,因为原先是两个有序链表,所以另一个没链接完的链表也是有序的,所以只需要直接链接到新链表的后面即可。

当然,这其中会有一些额外的情况,比如原先的两个链表有可能为空,那么此时只需要将另一个链表返回即可。

二,案例代码分析

根据上述我们的代码分析,接下来我们对于每一块代码进行一个简单的分析。

2.1 某个链表为空

首先是额外的情况,如果某一个链表为空,则返回另一个链表。

2.2整体循环 

然后第二个就是大体的循环,在新链表中插入较小的那个节点。涉及到两个链表中节点的比较,然后节点插入的时候,尾插的步骤。

因为这里涉及到的是尾插的步骤,所以我们不做过多解释。最主要的就是:当尾插不是头节点的时候,新链表的指针应该直接指向那个较小的节点。然后新链表的指针移动到那个元素上,继续插入下一个新节点。

2.3最后多于节点链接

当循环出来之后,就说明是某一个链表结束了,那么因为是有序链表,所以我们只需要将另一个多于的链表的节点连接到新链表的后面即可。

三,原码

struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2){
     struct ListNode*n1=list1;
     struct ListNode*n2=list2;
     struct ListNode*n3=NULL;
     struct ListNode*cur=NULL;
     if(n1==NULL)
     {
         return n2;
     }
     if(n2==NULL)
     {
         return n1;
     }
     while(n1&&n2)
     {
         if(n1->val >= n2->val)
         {
             if(cur==NULL)
             {
                 cur=n3=n2;
             }
             else
             {
                cur->next=n2;
                cur=n2;
             }
            n2=n2->next;
         } 
         else
         {
             if(cur==NULL)
             {
                 cur=n3=n1;
             }
             else
             {
                cur->next=n1; 
                cur=n1;
             }
             n1=n1->next;
         }
     }
    if(n1)
    {
        cur->next=n1;
    }
    if(n2)
    {
        cur->next=n2;
    }
    return n3; 
}

四,总结

那么通过该案例的分享,大家对于单链表的合并有没有更深的一个理解呢?

其实主要需要做的也就是一个步骤,我们需要一个新链表,然后依次尾插,最后将多于的链接到后面,这就是全部的合并过程。但是因为细节很多,以及新链表的指针的移动会出错,所以相对来说,单链表的合并还是很注重细节的。

好的,那么本文到此就结束啦!如有问题,还请各位小伙伴们指正呀!

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值