19-咸鱼学Java-两个有序链表的合并

如图
这里写图片描述
黑色的线为合并前的链表,蓝色的为合并后。
分析这个问题,可以发现此问题符合递归的四条基本法则。

1.基准情形。必须总要有某些基准情形,他无需递归就能解出。
2.不断推进。对于那些需要递归求解的情形,每一次递归调用都必须要使状况朝向一种基准情形推进。
3.设计法则。假设所有的递归调用都能运行。
4.合成效益法则。在求解一个问题的同一实例时,切勿在不同递归调用中做重复性的工作。

1.在最后一个节点的时候,只需要将最后一个节点链接到链表上即可。
2.每次递归调用只需要链接一个节点,在某一个链表为空的时候,链接另一个链表其余的节点。
3.此处需要进行三次四次判断,如果h1为空,则需要返回h2,如果h2为空则需返回h1,如果h1的data小于h2的data则需要把h1链接上,如果h1的data大于h2的data则链接h2。
4.每一次运行都会链接一部分节点,没有重复性工作。

代码

/**
     * 合并两个有序链表
     * @param h1
     * @param h2
     * @return 合成后的链表
     */ 
    public static Link2 RecursiveMergeLink(Link2 h1,Link2 h2)
    {
        Link2 h3 = new Link2();
        Entry h11 = h1.head.next;
        Entry h22 = h2.head.next;
        h3.head.next = RecursiveMergeEntry(h11, h22);
        return h3;
    }
    /**
     * 连接节点
     * @param h1
     * @param h2
     * @return 连接好后的第一个节点
     */
    public static Entry RecursiveMergeEntry(Entry h1,Entry h2)
    {
        Entry h3= null;             //临时变量保存当前需要被插入的节点
        if(h1 == null)              //如果h1等于null了则h1已经被连接完成,此处只需要链接剩下的h2即可
            return h2;  
        else if(h2 == null)         //如果h2等于null了则h2已经被连接完成,此处只需要链接剩下的h1即可
            return h1;
        else
        {
            if(h1.data < h2.data)   //如果h1比h2小
            {
                h3 = h1;            //则当前节点为h1
                h3.next = RecursiveMergeEntry(h1.next,h2);  //进行后续节点的连接
            }
            else if(h1.data > h2.data)//同上
            {
                h3 = h2;
                h3.next = RecursiveMergeEntry(h1,h2.next);
            }
            else                                    //当两个相等的时候,同时往后移位
            {
                h3 = h1;            //则当前节点为h1
                h3.next = RecursiveMergeEntry(h1.next,h2.next); //进行后续节点的连接
            }
            return h3;              //返回当前节点给上一层递归  当返回的时候 当前节点之后的节点都已经连接完成
        }   
    }

测试结果

public static void main(String[] args) {
        Link2 i = new Link2();
        Link2 j = new Link2();
        i.insertHead(9);
        i.insertHead(7);
        i.insertHead(5);
        i.insertHead(3);
        i.insertHead(1);
        j.insertHead(10);
        j.insertHead(8);
        j.insertHead(6);
        j.insertHead(4);
        j.insertHead(2);
        i.show();
        j.show();
        Link2 k = RecursiveMergeLink(i, j);
        k.show();
        }

结果
[1 3 5 7 9 ]
[2 4 6 8 10 ]
[1 2 3 4 5 6 7 8 9 10 ]

非递归实现

递归可以完成的事情,非递归肯定也可以完成。

    /**
     * 合并两个有序链表非递归
     * @param h1
     * @param h2
     * @return
     */
    public static Link2 MergeLink(Link2 h1,Link2 h2)
    {
        Link2 h3 = new Link2();
        if(h1 == null||h1.head.next==null)      //若某一个链表为空 直接返回另一个链表
            return h2;
        if(h2 == null||h2.head.next==null)
            return h1;
        Entry e1 = h1.head.next;                //获得两个链表的第一个数据域
        Entry e2 = h2.head.next;
        Entry e3 = h3.head;                     //获取临时链表的头结点
        while(e1!=null&&e2!=null)               //循环直到某一个链表为空
        {
            if(e1.data>e2.data)                 //进行判断
            {
                e3.next = e2;                   //连接
                e2 = e2.next;                   //移位
            }else if(e1.data<e2.data)           //同上
            {
                e3.next = e1;
                e1 = e1.next;
            }
            else                                //防止存在两个相等的元素,去除掉一个
            {
                e3.next = e2;                   
                e2 = e2.next;
                continue;
            }
            e3 = e3.next;                       //连接后将e3向后移动
        }
//      if(e1 == null)                          //当e1为空时,剩下的为h2 需要将h2剩余的节点e2连上
//      {
//          e3.next = e2;
//      }
//      else if(e2 == null)                     //同上
//      {
//          e3.next = e1;
//      }
        e3.next = e1==null?e2:e1;               //和上面if相同
        return h3;                              //返回临时链表h3
    }

测试结果

public static void main(String[] args) {
        Link2 i = new Link2();
        Link2 j = new Link2();
        i.insertHead(9);
        i.insertHead(7);
        i.insertHead(5);
        i.insertHead(3);
        i.insertHead(1);
        j.insertHead(10);
        j.insertHead(8);
        j.insertHead(6);
        j.insertHead(4);
        j.insertHead(2);
        i.show();
        j.show();
        Link2 k = MergeLink(i, j);
        k.show();
        }

结果
[1 3 5 7 9 ]
[2 4 6 8 10 ]
[1 2 3 4 5 6 7 8 9 10 ]

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值