• 合并两个有序链表


    思路:
    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
     */

     

  • 相关阅读:
    线段树、树状数组
    贪心算法(Fatmouse’Trade、今年暑假不AC)
    搜索+DP专题(背包问题、N个数选K个使平方和最大且和为X、divide by three, multiple by two、全排列、组合、N皇后、jugs、掉石头迷宫、斐波那契、最大连续子序列和、最长上升子序列、非常可乐、导弹拦截系统:最长不降子序列)
    计算机考研机试指南(九)——搜索(百鸡问题、ABC、胜利大逃亡、迷宫问题、C翻转、旋转矩阵、字符串匹配、)
    计算机考研机试指南(八)——图论(畅通工程、还是畅通工程、最短路、more is better、Freckles、legal or not、确定比赛名次、产生冠军、最短路径问题)
    String与StringBuffer与StringBuilder
    replace into
    eclipse迅速新建main函数
    数据库视图什么时候需要用到
    springboot实现拦截器
  • 原文地址:https://www.cnblogs.com/zh-xiaoyuan/p/15059385.html
Copyright © 2020-2023  润新知