剑指OfferJZ16:合并两个排序的链表-java版

这篇博客介绍了如何在Java中合并两个单调递增的链表,保持合并后的链表依然单调不减。通过创建一个虚拟头结点作为哨兵,避免边界问题,简化代码。在遍历两个链表的过程中,比较当前节点的值并将其较小者添加到合并链表中,直到其中一个链表为空,然后将非空链表剩余部分追加到合并链表。该方法类似于归并排序的合并步骤。
摘要由CSDN通过智能技术生成

剑指OfferJZ16:合并两个排序的链表-java版

JZ16 合并两个排序的链表

描述
输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。
示例1
输入:

{1,3,5},{2,4,6}

返回值:

{1,2,3,4,5,6}

建立一个用于存放合并后的链表的大链表 listNode
由于两个链表中数字都是有序的,我们可以这样:

  • 如果两个链表list1和list2都有数字,这时我们将链表list1的第一个数和链表list2的第一个数比较,将小的那个数移入到listNode中,以此类推,

  • 当合并后只剩有一个链表有数字时,直接将这个链表剩下的所有数字移入listNode中

该思路类似于归并排序中的“合”,只是归并排序中用的是数组,而这道题用的是链表罢了,参考归并排序
在这里插入图片描述
解题思路比较简单,但这道链表算法题需要注意一个问题:
一般创建单链表,都会设一个虚拟头结点,也叫哨兵,因为这样每一个结点都有一个前驱结点。

哨兵,顾名思义,是用来解决国家之间边界问题的,不直接参与生产活动。同样,计算机科学中提到的哨兵,也用来解决边界问题
不带哨兵节点的链表,插入或删除操作发生在第一个节点时,表头指针都要变化,需要额外的处理。带哨兵节点的链表,插入或删除时,不论操作的位置,表头都不变,不需要额外的判断;
所以我们可以申请一个头结点,作为原本的第一个结点的前驱结点,问题也就解决了。(如果用的是双链表,就需要在头尾各加一个哨兵)

使用哨兵的其它好处: 在循环语句中使用哨兵的好处往往在于可以使代码简洁,而非提高速度。举例来说,使用哨兵使链表的代码变得简洁了
我们应当慎用哨兵。假如有许多个很短的链表,它们的哨兵所占用的额外的存储空间会造成严重的额存储浪费。


public class jz16 {
    public ListNode Merge(ListNode list1,ListNode list2) {
        ListNode listNode = new ListNode(0);//合并的链表
        ListNode cur = listNode;//cur哨兵节点:解决边界问题,使代码更简洁
        while(list1!=null && list2!=null){
            if(list1.val<list2.val){
                cur.next=list1;//将小的数字放入到合并的链表中
                list1=list1.next;
            }else {
                cur.next=list2;
                list2=list2.next;
            }
            cur=cur.next;
        }
        //以下针对有一个链表数字都合并完了,另一个链表还没合并完的情况
        if(list1==null){//说明链表list2还有剩余的数字
            cur.next=list2;//将list2剩余的所有数字直接放入到合并链表中(因为这里剩下的数字肯定是有序的)
        }
        if(list2==null){//说明链表list1还有剩余的数字
            cur.next=list1;//将list1剩余的所有数字直接放入到合并链表中(因为这里剩下的数字肯定是有序的)
        }
        return listNode.next;
    }
}
class ListNode{
    int val;
    ListNode next=null;
    ListNode(int val){
        this.val =val;
    }
}

在这里插入图片描述

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

李莲花*

多谢多谢,来自一名大学生的感谢

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

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

打赏作者

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

抵扣说明:

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

余额充值