合并两个有序的单链表,合并之后的链表依然有序

 希望大佬多多指正

public class SingliLinkedListDemo {

    public static void main(String[] args) {
        //测试
        //创建节点
        HeroNode hero1 = new HeroNode(1, "宋江", "及时雨");
        HeroNode hero3 = new HeroNode(3, "吴用", "智多星");
        HeroNode hero4 = new HeroNode(6, "林冲", "豹子头");
        HeroNode hero2 = new HeroNode(10, "小旋风", "柴进");

        //创建一个单链表
        SingleListedList singleListedList = new SingleListedList();

         //加入按照编号的顺序
        singleListedList.addByOrder(hero1);
        singleListedList.addByOrder(hero4);
        singleListedList.addByOrder(hero3);
        singleListedList.addByOrder(hero2);
         //展示链表
        singleListedList.show();
        System.out.println("----------------------------------------------------");
        //合并两个有序的单链表,合并之后的链表依然有序【课后练习.】

        HeroNode hero5 = new HeroNode(2, "卢俊义", "玉麒麟");
        HeroNode hero6 = new HeroNode(4, "入云龙", "公孙胜");
        HeroNode hero7 = new HeroNode(7, "霹雳火", "秦明");
        HeroNode hero8 = new HeroNode(13, "花和尚", "鲁智深");
        HeroNode hero9 = new HeroNode(14, "行者", "武松");

        //创建一个单链表
        SingleListedList singleListedList2 = new SingleListedList();
        //按照编号的顺序加入
        singleListedList2.addByOrder(hero6);
        singleListedList2.addByOrder(hero7);
        singleListedList2.addByOrder(hero5);
        singleListedList2.addByOrder(hero8);
        singleListedList2.addByOrder(hero9);
        singleListedList2.show();
        System.out.println("----------------------------------------------------");
        System.out.println("合并后:");
        SingleListedList singleListedList3 = new SingleListedList();
        mergeList(singleListedList.getHead(), singleListedList2.getHead(), 
                        singleListedList3.getHead());
        singleListedList.show();
    }

 public static void mergeList(HeroNode head1, HeroNode head2, HeroNode newHead) {

        //创建一个新链表
        HeroNode curNew = newHead;
        HeroNode cur1 = head1.next;//链表1,当前节点
        HeroNode cur2 = head2.next;//链表2,当前节点

        //
        if (head1.next==null&& head2.next==null){
            System.out.println("两个要合并的链表都为空,无法合并");
            return;
        }


        //2.当两个节点都不为null时,比较添加
        while (cur1 != null && cur2 != null) {
            //都不为空
            //比较两个节点的no
            if (cur1.no <= cur2.no) {
                //将cur1加入到curNew的next
                curNew.next = cur1;
                //将curNew后移
                curNew = curNew.next;
                //将cur1后移
                cur1 = cur1.next;
            } else {
                //将cur2加入到curNew的next
                curNew.next = cur2;
                //将curNew后移
                curNew = curNew.next;
                //将cur1后移
                cur2 = cur2.next;
            }
        }


        //3.当其中有一个走到null时,跳出循环
       if (cur1==null){
           while (cur2!=null){
               //将cur2加入到curNew的next
               curNew.next = cur2;
               //将curNew后移
               curNew = curNew.next;
               //将cur1后移
               cur2 = cur2.next;
           }
       }else {//此时cru2==null
           while (cur1!=null){
               //将cur1加入到curNew的next
               curNew.next = cur1;
               //将curNew后移
               curNew = curNew.next;
               //将cur1后移
               cur1 = cur1.next;
           }
       }


    }
//定义一个单链表
class SingleListedList {
    //创建头节点
    private HeroNode head = new HeroNode();

    //获取头节点
    public HeroNode getHead() {
        return head;
    }

    //定义判断链表为空
    public boolean isEmpty() {
        if (head.next == null) {
            return true;
        }
        return false;
    }

    //定义展示节点的方法
    public void show() {
        //判断链表是否为空
        if (head.next == null) {
            //为空
            System.out.println("链表为空");
            return;
        }
        //因为头节点不能动,定义一个辅助节点来遍历
        HeroNode temp = head.next;
        while (true) {
            //判断节点是否到最后
            if (temp == null) {
                break;
            }
            //输出节点信息
            System.out.println(temp);
            //将temp后移
            temp = temp.next;
        }
    }

    /**************************************************/
    //1、将节点添加到链表的最后
    public void add(HeroNode heroNode) {
           /* 因为头节点不能动
            使用临时变量来操作链表*/
        HeroNode temp = head;
        //遍历节点,使用循环,使得temp指向最后一个节点
        while (true) {
            //判断是否到最后
            if (temp.next == null) {
                break;
            }
            //不是最后一个节点,将temp后移
            temp = temp.next;
        }
        //循环退出时,temp就指向最后一个节点
        //将新节点添加到最后一个节点的最后面
        temp.next = heroNode;

    }

    /**************************************************/
    //2、根据排名将节点添加到链表的指定位置(如果有这个排名,则添加失败,并给出提示)
    public void addByOrder(HeroNode heroNode) {
         /* 因为头节点不能动
            使用临时变量来操作链表*/
        HeroNode temp = head;
        boolean flag = false;//flag标志添加的编号是否存在,默认为false
        //遍历链表,判断满足条件
        while (true) {
            if (temp.next == null) { //到了链表尾部
                break;
            }
            if (temp.next.no > heroNode.no) {//找到了位置,在temp的后面插入
                break;
            } else if (temp.next.no == heroNode.no) {//该节点的编号已存在
                flag = true;
                break;
            }
            temp = temp.next;//后移,遍历当前链表
        }
        //判断flag的值
        if (flag) {//不能添加,说明编号已存在
            System.out.printf("准备待插入的英雄编号 %d 已经存在,不能再加入\n", heroNode.no);
        } else {
            //将新节点添加到temp后面
            //1.将原先temp后后一位的节点地址赋值给新节点的next
            heroNode.next = temp.next;
            //2.将新节点的地址赋值给temp的next
            temp.next = heroNode;
        }

    }

    /**************************************************/
    //3.完成修改节点的信息,根据no编号来修改,即no编号不能改
    public void update(HeroNode newHeroNode) {
        //判断链表是否为空
        if (isEmpty()) {
            System.out.println("链表为空,无法进行修改");
            return;
        }
        //不为空
        //根据no,找到需要修改的节点
        //定义一个辅助变量
        HeroNode temp = head.next;//temp为第一个节点的地址
        boolean flag = false;//flag标志修改的编号是否找到,默认为false
        while (true) {
            if (temp.no == newHeroNode.no) {//找到需要修改的节点
                flag = true;
                break;
            }
            if (temp.next == null) {//到了链表的最后一个节点
                break;
            }
            temp = temp.next;
        }
        if (flag) {//找到了需要修改的节点
            //修改信息
            temp.name = newHeroNode.name;
            temp.nickname = newHeroNode.nickname;
        } else {//不存在该编号的节点
            System.out.printf("需要修改的节点%d不存在,无法进行修改/n", newHeroNode.no);
        }
    }

    /**************************************************/
    //4.根据no,删除节点
    //head不能动,因此我们需要一个temp辅助节点找到待删除节点的 前 一个节点
    //说明我们在比较时,是temp.next.no和需要删除的节点的no比较
    public void del(int no) {
        //判断链表是否为空
        if (isEmpty()) {//空表
            System.out.println("空表,无法删除!");
            return;
        }
        //不为空
        //辅助节点
        HeroNode temp = head;
        boolean flag = false;//flag标志删除的编号是否找到,默认为false
        //找到no节点的前一个节点
        while (true) {
            if (temp.next == null) {//到链表的最后一个节点,没有找到
                break;
            }
            if (temp.next.no == no) {//找到节点,即temp的下一个节点
                flag = true;
                break;
            }
            temp = temp.next;

        }
        //判断flag
        if (flag) {//找到,此时temp是带删除节点的前一个节点地址
            //删除节点
            //将temp的next的next赋值给temp的next
            temp.next = temp.next.next;
        } else {//不存在该编号的节点
            System.out.printf("要删除的节点 %d 不存在,无法进行删除/n", no);
        }
    }
    /**************************************************/


}


//定义一个HeroNode,每一个HeroNode 对象就是一个节点
class HeroNode {
    public int no;
    public String name;
    public String nickname;
    public HeroNode next;//指向下一个节点

    public HeroNode() {
    }

    //构造器
    public HeroNode(int no, String name, String nickname) {
        this.no = no;
        this.name = name;
        this.nickname = nickname;
    }

    @Override
    public String toString() {
        return "HeroNode{" +
                "no=" + no +
                ", name='" + name + '\'' +
                ", nickname='" + nickname + '\'' +
                '}';
    }
}

对于 mergeList方法的体会:

    1.判断两个要合并的链表是否为空

    2.当两个节点都不为null时,比较添加

    3.当其中有一个走到null时,跳出循环

注意:第二步和第三步不能调换位置
如果调换2和3步:
   只会将head1加入到newHead,因为
   第三步:在判断cur1!=null后,执行else,
   此时cur1!=null,默认cur2==null,但是实际情况

cur2!=null,
   会将head1中全部节点加入到newHead;
   当所有节点都加入完毕后,cur1 ==null,跳出循环、
   执行第二步:此时实际情况cur1 ==null,cur2!=null
   判断后,跳出循环,返回结束。
   所以在newHead中仅仅存在head1的数据

 希望大佬多多指正 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值