数据结构与算法-合并两个有序链表

数据结构与算法-合并两个有序链表

大家好,欢迎回到我们的算法学习系列。今天,我们将探讨一个在链表操作中非常实用的问题——合并两个有序链表。

什么是有序链表?

有序链表是指其中的节点按值递增或递减排列的链表。合并两个有序链表是指将两个已经排序好的链表合并成一个新的有序链表。

问题描述

给定两个有序链表的头节点,将它们合并为一个新的有序链表,并返回新链表的头节点。新链表应该通过拼接给定的两个链表的所有节点组成。

示例

  • 输入:1 -> 2 -> 41 -> 3 -> 4
    输出:1 -> 1 -> 2 -> 3 -> 4 -> 4

解决思路

我们可以通过迭代的方法来合并两个有序链表。基本思路是比较两个链表的头节点,将较小的节点添加到结果链表中,并移动指针到下一个节点,直到遍历完两个链表。

实现代码

下面是用JavaScript实现这个算法的代码:

function ListNode(val) {
  this.val = val;
  this.next = null;
}

function mergeTwoLists(l1, l2) {
  let dummy = new ListNode(0); // 创建哨兵节点,便于操作
  let current = dummy;

  while (l1 !== null && l2 !== null) {
    if (l1.val <= l2.val) {
      current.next = l1;
      l1 = l1.next;
    } else {
      current.next = l2;
      l2 = l2.next;
    }
    current = current.next;
  }

  // 合并剩余的节点
  current.next = (l1 !== null) ? l1 : l2;

  return dummy.next; // 返回合并后的链表的头节点
}

代码解析

  1. 定义节点结构ListNode 是一个链表节点的构造函数,每个节点有一个值 val 和一个指向下一个节点的指针 next
  2. 创建哨兵节点:我们创建一个哨兵节点 dummy,它的 next 指针指向结果链表的头节点。这个哨兵节点使得链表操作更加方便。
  3. 初始化指针:定义一个指针 current,初始时指向哨兵节点。
  4. 遍历两个链表
    • 比较两个链表的当前节点,将较小的节点添加到结果链表中,并移动指针到下一个节点。
    • 重复上述操作,直到遍历完两个链表中的一个。
  5. 合并剩余节点:如果其中一个链表遍历完,直接将另一个链表剩余的节点连接到结果链表的末尾。
  6. 返回结果:返回哨兵节点的 next 指针,即合并后的链表的头节点。

图解

让我们通过图解来理解合并过程:

初始链表:

l1: 1 -> 2 -> 4
l2: 1 -> 3 -> 4

第一步:

dummy -> 1
l1: 2 -> 4
l2: 1 -> 3 -> 4

第二步:

dummy -> 1 -> 1
l1: 2 -> 4
l2: 3 -> 4

第三步:

dummy -> 1 -> 1 -> 2
l1: 4
l2: 3 -> 4

依次类推,直到两个链表都遍历完,最终得到合并后的链表。

小结

今天,我们介绍了合并两个有序链表的问题及其解决方法。通过迭代的方法,我们可以高效地将两个有序链表合并为一个新的有序链表,这是一个在实际开发中非常实用的操作。

感谢大家的阅读!如果你有任何问题或建议,欢迎在评论区留言。

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

前端每日三省

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值