链表——两个有序单链表的合并

示意图:

这里写图片描述

这里写图片描述

/*
   * 单链表的合并
*/
class Outer5 {
    class Entry {
        int data;
        Entry next;

        public Entry() {
            data = 0;
            next = null;
        }

        public Entry(int data) {
            this.data = data;
            next = null;
        }
    }

    private Entry head = new Entry();

    /**
     *尾插法
     * @param val 需要插入的数据
     */
    public void insertlast(int val) {
        Entry cur = head;
        while(cur.next != null) {
            cur = cur.next;
        }
        Entry entry = new Entry(val);
        cur.next = entry;
    }

    /*
     * 合并有序链表
     * @param L1 
     * @param L2
     * @return 合并好的新链表
    */
    public static Outer5 HebinLianbiao(Outer5 L1,Outer5 L2) {
        Outer5 L3 = new Outer5();
        Entry p1 = L1.head.next;
        Entry p2 = L2.head.next;
        Entry p = L3.head;
        if(L1 == null || L1.head.next == null) {
            return L2;
        }
        if(L2 == null || L2.head.next == null) {
            return L1;
        }
        while(p1 != null && p2!= null) {
            if(p1.data < p2.data) {
                p.next = p1;
                p1 = p1.next;
            }
            else if(p1.data > p2.data) {
                p.next = p2;
                p2 = p2.next;
            }else {
                p.next = p1;
                p1 = p1.next;
            }
            p = p.next;
        }
       if(p1 == null) {
           p.next = p2;
       }
       else if(p2 == null) {
           p.next = p1;
       }
       return L3;
    }

    //输出
    public void show() {
        Entry cur = head;
        while(cur.next != null) {

            cur = cur.next;
            System.out.print(cur.data+" ");
        }
        System.out.println();
    }
}
public class Lianxi1 {

    public static void main(String[] args) {
        Outer5 s= new Outer5();
        System.out.println("链表1");
        s.insertlast(25);
        s.insertlast(45);
        s.insertlast(65);
        s.insertlast(85);
        s.show();
        Outer5 x= new Outer5();
        System.out.println("链表2");
        x.insertlast(15);
        x.insertlast(35);
        x.insertlast(55);
        x.insertlast(75);
        x.insertlast(95);
        x.show();
        System.out.println("合并后链表");
        Outer5 h = Outer5.HebinLianbiao(s,x);
        h.show();
    }

}

这里写图片描述

上面的合并方法比较好理解,但写的话最好是调用其他方法算,别写在一个方法里面,以下是合并链表的其他两种方法:

1.递归法:

/**
     * 合并两个有序链表
     * @param h1
     * @param h2
     * @return 合成后的链表
     */ 
    public static Outerq RecursiveMergeLink(Outerq h1,Outerq h2)
    {
        Outerq h3 = new Outerq();
        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;              //返回当前节点给上一层递归  当返回的时候 当前节点之后的节点都已经连接完成
        }   
    }

2.非递归法:

/**
     * 合并两个有序链表
     * @param h1
     * @param h2
     * @return 合成后的链表
     */ 
    public static Outerq RecursiveMergeLink(Outerq h1,Outerq h2)
    {
        Outerq h3 = new Outerq();
        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 Outerq MergeLink(Outerq h1,Outerq h2) {
        Outerq h3 = new Outerq();
        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
    }

猜你喜欢

转载自blog.csdn.net/qq2899349953/article/details/80233892