合并两个有序链表

思路:
1、异常判断
  1)两个单链表都没空,则返回null
  2)链表1为空,则返回链表2、反之返回链表1。
  3)比较两个链表头结点的大小。如果链表1的头结点比链表2的头结点小,则将新链表的头结点、尾节点指向链表1的头结点,同时将链表1的头结点更新为下一个结点。
       反之则将新链表的头结点指向链表2的头结点、尾节点,同时更新链表2的头结点为下一个结点。
2、使用while循环,当两个单链表都不为nu的情况下:
      如果链表1的头结点<链表2的头结点,则将新链表的尾结点指向链表1的头结点,同时将更新后的新链表的最后一个结点更新成head1并将链表1的头结点后移。
      反之,则同样的操作用于链表2。
3、循环结束后,判断两个链表中是否有空的链表,如果不为空,则将该链表的头结点及后面的结点直接放入新链表的末尾。
4、最后返回新链表的头结点

总结:

  代码实现 

package exercise;

/**
 * @author : zhang
 * @version : 1.0
 * @date : Create in 2021/7/25
 * @description :合并两个有序的链表
 * 链表1:1 --> 3 --> 5 --> 6
 * 链表1:2 --> 4 --> 7 --> 8
 * 合并后的链表:1 --> 2 --> 3 --> 4 --> 5 --> 6 --> 7 --> 8
 */
public class TestMergeTwoLists {
    public static void main(String[] args) {
        //1、创建两个单链表
        //链表1
        Node node1_4 = new Node(6);
        Node node1_3 = new Node(5, node1_4);
        Node node1_2 = new Node(3, node1_3);
        Node node1_1 = new Node(1, node1_2);

        //链表2
        Node node2_4 = new Node(8);
        Node node2_3 = new Node(7, node2_4);
        Node node2_2 = new Node(4, node2_3);
        Node node2_1 = new Node(2, node2_2);

        // 2、合并两个有序的单链表
        //Node headNode = mergeTwoLists(node1_1, node2_1);
        Node headNode = merge(node1_1, node2_1);
        print(headNode);
    }
    
    //遍历链表
    public static void print(Node headNode) {
        Node tempNode = headNode;
        while (tempNode != null) {
            System.out.println(tempNode.data);
            tempNode = tempNode.next;
        }
    }

    //方式1:递归实现合并
    public static Node merge(Node head1,Node head2){
        if (head1 == null) return head2;
        if (head2 == null) return  head1;

        Node head = null;
        if (head1.data <= head2.data){
            head = head1;
            head.next = merge(head1.next,head2);
        }else{
            head = head2;
            head.next = merge(head1,head2.next);
        }
        return head;
    }

    //方式2:非递归实现合并    
    /**
     * 合并两个有序的单链表   
     * @param head1 链表1的首节点
     * @param head2 链表2的首节点
     * @return 返回合并后链表的首节点
     */
    public static Node mergeTwoLists(Node head1, Node head2) {
        //1、处理head1和head2为null的情况
        if (head1 == null && head2 == null) {
            return null;
        }
        if (head1 == null) {
            return head2;
        }
        if (head2 == null) {
            return head1;
        }
        //2、定义headNode和lastNode,分别作为合并后链表的首节点和尾结点
        Node headNode = null;
        Node lastNode = null;
        //3、获取head1和head2中数据值较小的节点,并设置为合并后链表的首节点和尾结点
        if (head1.data > head2.data) {
            headNode = head2;
            lastNode = head2;
            //更新head2的值,让head2指向下一个节点
            head2 = head2.next;
        } else {
            headNode = head1;
            lastNode = head1;
            //更新head1的值,让head1指向下一个节点
            head1 = head1.next;
        }

        //4、定义一个循环,用于依次获得链表1和链表2中数据值较小的节点,并把该节点添加到合并后链表的末尾
        while (head1 != null && head2 != null) {
            if (head1.data > head2.data) {
                lastNode.next = head2;
                lastNode = head2;
                head2 = head2.next;
            } else {
                lastNode.next = head1;
                lastNode = head1;
                head1 = head1.next;
            }
        }

        //5、循环执行完毕,如果某个链表的首节点不为null,那么我们就将这个链表的首节点及之后的节点添加到合并后链表的末尾
        if (head1 == null) {
            lastNode.next = head2;
        } else {
            lastNode.next = head1;
        }

        //6、返回合并后链表的尾结点
        return headNode;
    }

    private static class Node {
        private int data;
        private Node next;

        public Node(int data) {
            this.data = data;
        }

        public Node(int data, Node next) {
            this.data = data;
            this.next = next;
        }
    }
}

/**
 * 1
 * 2
 * 3
 * 4
 * 5
 * 6
 * 7
 * 8
 */

 

原文地址:https://www.cnblogs.com/zh-xiaoyuan/p/15059385.html