【链表OJ 5】合并两个有序链表

简介: 【链表OJ 5】合并两个有序链表

前言:

       🎈欢迎大家来到Dream_Chaser~的博客🎈

本文收录于 C--数据结构刷题的专栏中 -->http://t.csdn.cn/n6UEP

       首先欢迎大家的来访,其次如有错误,非常欢迎大家的指正!我会及时更正错误!


一.合并两个有序链表


来源:21. 合并两个有序链表 - 力扣(LeetCode)

题目:

29df67ac09a44692972f0b93680a3669.png

解析:

       函数的参数是两个指向 ListNode 结构体的指针, ListNode 是一个常见的链表节点结构。ListNode 结构一般包含两个成员:一个是存储节点值的变量(比如 val ),另一个是指向下一个节点的指针(比如 next )。

       

       目的是把两个已排序的链表( list1 list2 )合并为一个新的已排序的链表,并返回这个新链表的头节点


1.1核心逻辑        

以下是该函数的核心逻辑:

  1. 首先,如果 list1list2 是空链表(即NULL),函数会直接返回另一个链表。这是因为合并一个空链表和一个非空链表的结果就是那个非空链表。
  2. 接着,它进入了一个while循环。在这个循环中,只要list1list2都不为空,就会比较它们当前节点的值。如果 list1 的当前节点值小于 list2 的当前节点值,就把list1 的当前节点加入到新链表中(先让tail -> next= list1  ,然后tail=tail->next 指向list1),,然后 list1 把向后移动一位,。否则,就把list2的当前节点加入到新链表中(先让tail -> next= list2  ,然后tail=tail->next 指向list2),然后把list2向后移动一位。这样可以保证新链表的节点是按照升序排列的。
  3. headtail 是两个辅助指针,用来构建新链表。head指向新链表的头节点,tail指向新链表的尾节点。每次添加一个新节点时,都会更新tail指向新加入的节点。
  4. list1list2 中有一个被完全遍历(即变为NULL)后,while循环就会结束。此时,如果list1list2中还有剩余的节点,就把这些节点全部加入到新链表的尾部。这是可以做的,因为这些剩余的节点已经是按照升序排列的,而且它们的所有值都大于新链表中已有节点的值。
  5. 最后,函数返回新链表的头节点 head


1.2两元素相同时选谁尾插?

我解释一下为什么当list1指向的元素与list2指向的元素大小相等时,用list2尾插:

在两个链表元素相等的情况下,默认选择lsit1作为较大的元素。


list1list2指向的元素都是1时,来到了if else 语句,如果条件为真,进入循环,则证明选择list2作为较大元素,反之选择list1为较大元素

801a95b4bc2246fe96c16016a1d810bc.png

结果程序来到了else处,此刻list2小于list1,选择list2尾插,说明list1list2

d3704d4ec3d741868694891ceca85a39.png

动图解析:(点进去放大看更清晰)

8f5e78b68c874363bdf60a1e8fa212c0.gif

struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2)
{
   if(list1==NULL)
      return list2;//若第一个链表为 NULL,直接返回第二个链表
   if(list2 ==NULL)
      return list1;//若第二个链表为 NULL,直接返回第一个链表
   struct ListNode* head=NULL,*tail=NULL;
   while(list1 && list2)
   {
     if(list1->val < list2->val)//比较链表元素谁大,核心是小的先为尾插
     {
         if(tail==NULL)
          {
             head= tail= list1;
          }
         else
          {
            tail->next=list1;//让新链表的结点与list1指向的元素想链接
            tail=tail->next;
          }
        list1=list1->next;//list1往原始链表后面遍历
     }
   else
   {
      if(tail == NULL)
       {
           head= tail =list2;
       }
      else
       {
          tail->next=list2;//让新链表的结点与list2指向的元素想链接
          tail=tail->next;
      }
         list2=list2->next;//list2往原始链表后面遍历
      }
   }
//若其中一个链表已经遍历到NULL,直接把另一个链表的所有元素原封不动拷贝到新链表
     if(list1)
     {
        tail->next=list1;
     }
     if(list2)
     {
      tail->next=list2;
     }
    return head;
 }

代码执行:

7070d32cc1ef4f639510a45494ef53c1.png

  本文到此结束,如有错误,随时欢迎大家指正!

相关文章
|
1天前
《剑指offer》——合并两个排序的链表
《剑指offer》——合并两个排序的链表
|
1天前
|
算法
LeetCode刷题---21.合并两个有序链表(双指针)
LeetCode刷题---21.合并两个有序链表(双指针)
|
1天前
数据结构——链表OJ题
数据结构——链表OJ题
|
1天前
|
Java C语言
剑指offer(牛客)——合并两个排序的链表
剑指offer(牛客)——合并两个排序的链表
8 1
|
1天前
【力扣】21. 合并两个有序链表
【力扣】21. 合并两个有序链表
|
1天前
|
C语言
反转链表、链表的中间结点、合并两个有序链表【LeetCode刷题日志】
反转链表、链表的中间结点、合并两个有序链表【LeetCode刷题日志】
|
1天前
|
算法
顺序表、链表相关OJ题(2)
顺序表、链表相关OJ题(2)
|
1天前
|
存储 算法
顺序表、链表相关OJ题(1)
顺序表、链表相关OJ题(1)
|
1天前
Leecode之合并两个有序链表
Leecode之合并两个有序链表
|
1天前
|
算法
LeetCode刷题---19. 删除链表的倒数第 N 个结点(双指针-快慢指针)
LeetCode刷题---19. 删除链表的倒数第 N 个结点(双指针-快慢指针)