• 面试算法29:排序的循环链表


    问题

    在一个循环链表中节点的值递增排序,请设计一个算法在该循环链表中插入节点,并保证插入节点之后的循环链表仍然是排序的。
    在这里插入图片描述

    分析

    首先分析在排序的循环链表中插入节点的规律。当在图4.15(a)的链表中插入值为4的节点时,新的节点位于值为3的节点和值为5的节点之间。这很容易理解,为了使插入新节点的循环链表仍然是排序的,新节点的前一个节点的值应该比新节点的值小,后一个节点的值应该比新节点的值大。

    但是特殊情况需要特殊处理。如果新节点的值比链表中已有的最大值还要大,那么新的节点将被插入最大值和最小值之间。如果新节点的值比链表中已有的最大值还要大,那么新的节点将被插入最大值和最小值之间。
    在这里插入图片描述
    在上面的规则中,总是先试图从链表中找到符合条件的相邻的两个节点。如果开始的时候链表中的节点数小于2,那么应该有两种可能。第1种可能是开始的时候链表是空的,一个节点都没有。此时插入一个新的节点,该节点成为循环链表中的唯一节点,那么next指针指向节点自己,如图4.17(a)所示。第2种可能是开始的时候链表中只有一个节点,插入一个新的节点之后,两个节点的next指针互相指向对方,如图4.17(b)所示。
    在这里插入图片描述

    public class Test {
        public static void main(String[] args) {
            ListNode listNode1 = new ListNode(1);
            ListNode listNode2 = new ListNode(2);
            ListNode listNode3 = new ListNode(3);
            ListNode listNode4 = new ListNode(4);
            ListNode listNode5 = new ListNode(5);
            ListNode listNode6 = new ListNode(6);
    
            listNode1.next = listNode2;
            listNode2.next = listNode3;
            listNode3.next = listNode5;
            listNode5.next = listNode6;
            listNode6.next = listNode1;
    
            ListNode result = insert(listNode1, 4);
            while (result != null) {
                System.out.println(result.val);
                result = result.next;
            }
        }
    
        public static ListNode insert(ListNode head, int insertVal) {
            ListNode node = new ListNode(insertVal);
            if (head == null) {// 没有节点
                head = node;
                head.next = head;
            }
            else if (head.next == head) {// 只有一个节点
                head.next = node;
                node.next = head;
            }
            else {
                insertCore(head, node);
            }
    
            return head;
        }
    
        private static void insertCore(ListNode head, ListNode node) {
            ListNode cur = head;
            ListNode next = head.next;
            ListNode biggest = head;
            while (!(cur.val <= node.val && next.val >= node.val) && next != head) {
                cur = next;
                next = next.next;
                if (cur.val >= biggest.val)
                    biggest = cur;
            }
    
            if (cur.val <= node.val && next.val >= node.val) {
                cur.next = node;
                node.next = next;
            }
            else {
                node.next = biggest.next;
                biggest.next = node;
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
  • 相关阅读:
    【Springboot】动态配置数据源,系统自动辨认服务端与本地端数据源
    Hive实现查询左表有右表没有的记录
    Linux实操篇-组管理和权限管理
    腾讯云CVM服务器操作系统镜像大全
    可视化服务编排在金融APP中的实践
    Spring复习面试题
    创建百科词条 烘托人物形象 提升形象力
    FreeRTOS 任务状态查询
    Git版本管理
    未找到重要体积,且场景太大,自动合成的体积无法产生良好的效果。请添加一个紧密包裹的lightmass重要体积来优化场景质量及光照构建时间。
  • 原文地址:https://blog.csdn.net/GoGleTech/article/details/133905467