十大排序算法(java实现)

注:本篇仅用来自己学习,大量内容来自菜鸟教程(地址:1.0 十大经典排序算法 | 菜鸟教程)

排序算法可以分为内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存。常见的内部排序算法有:插入排序、希尔排序、选择排序、冒泡排序、归并排序、快速排序、堆排序、基数排序等。【冒泡、插入、选择、快速、归并排序面试中出现概率极高】

1.冒泡排序

冒泡排序(Bubble Sort) 是一种简单直观的排序。它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。

算法步骤:

  • 比较相邻的元素,如果第一个比第二个大,就交换他们两个。

  • 对每一对相邻元素进行同样工作,直到最后的元素是最大的数。

  • 重复上述工作,直到数字是有序的。

实现代码:

public class BubbleSort implements IArraySort {
​
    @Override
    public int[] sort(int[] sourceArray) throws Exception {
        // 对 arr 进行拷贝,不改变参数内容
        int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);
​
        for (int i = 1; i < arr.length; i++) {
        // 设定一个标记,若为true,则表示此次循环没有进行交换,也就是待排序列已经有序,排序已经完成。
            boolean flag = true;
​
            for (int j = 0; j < arr.length - i; j++) {
                if (arr[j] > arr[j + 1]) {
                    int tmp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = tmp;
​
                    flag = false;
                }
            }
​
            if (flag) {
                break;
            }
        }
        return arr;
    }
}

2.选择排序

选择排序是一种简单直观的排序算法,其基本思想是每次从待排序的元素中选择最小(或最大)的元素,放置到已排序序列的末尾(或开头),直到所有元素都排序完成为止。

算法步骤:

  • 在未排序的序列中找出最小(大)元素,存放在排序序列的起始位置。

  • 接着从剩余未排序的序列中继续寻找最小(大)元素,然后放到已排序序列的末尾。

  • 重复上述步骤,直到所有元素均排序完毕。

实现代码:

public class SelectionSort implements IArraySort {
​
    @Override
    public int[] sort(int[] sourceArray) throws Exception {
        int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);
​
        // 总共要经过 N-1 轮比较
        for (int i = 0; i < arr.length - 1; i++) {
            int min = i;
​
            // 每轮需要比较的次数 N-i
            for (int j = i + 1; j < arr.length; j++) {
                if (arr[j] < arr[min]) {
                    // 记录目前能找到的最小值元素的下标
                    min = j;
                }
            }
​
            // 将找到的最小值和i位置所在的值进行交换
            if (i != min) {
                int tmp = arr[i];
                arr[i] = arr[min];
                arr[min] = tmp;
            }
​
        }
        return arr;
    }
}

3.插入排序

插入排序是一种简单直观的排序算法,其基本思想是将待排序的元素逐个插入到已经排序的序列中的合适位置,直到整个序列都排好序为止。

算法步骤:

  • 将第一个元素视为已排序序列,其余元素为待排序序列。

  • 从第二个元素开始,逐个将待排序序列中的元素插入到已排序序列中的合适位置。

  • 对于每一个待排序元素,从其前一个元素开始,依次向前比较,直到找到合适的插入位置。

  • 插入元素后,已排序序列长度加一,待排序序列长度减一。

  • 重复以上步骤,直到所有元素都被插入到已排序序列中,排序完成。

代码实现:

public class InsertSort implements IArraySort {
​
    @Override
    public int[] sort(int[] sourceArray) throws Exception {
        // 对 arr 进行拷贝,不改变参数内容
        int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);
​
        // 从下标为1的元素开始选择合适的位置插入,因为下标为0的只有一个元素,默认是有序的
        for (int i = 1; i < arr.length; i++) {
​
            // 记录要插入的数据
            int tmp = arr[i];
​
            // 从已经排序的序列最右边的开始比较,找到比其小的数
            int j = i;
            while (j > 0 && tmp < arr[j - 1]) {
                arr[j] = arr[j - 1];
                j--;
            }
​
            // 存在比其小的数,插入
            if (j != i) {
                arr[j] = tmp;
            }
​
        }
        return arr;
    }
}

4.希尔排序

希尔排序的基本思想是:先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,待整个序列中的记录"基本有序"时,再对全体记录进行依次直接插入排序。

算法步骤:

  • 选择一个增量序列 t1,t2,……,tk,其中 ti > tj, tk = 1;

  • 按增量序列个数 k,对序列进行 k 趟排序;

  • 每趟排序,根据对应的增量 ti,将待排序列分割成若干长度为 m 的子序列,分别对各子表进行直接插入排序。仅增量因子为 1 时,整个序列作为一个表来处理,表长度即为整个序列的长度。

代码实现:

public static void shellSort(int[] arr) {
    int length = arr.length;
    int temp;
    for (int step = length / 2; step >= 1; step /= 2) {
        for (int i = step; i < length; i++) {
            temp = arr[i];
            int j = i - step;
            while (j >= 0 && arr[j] > temp) {
                arr[j + step] = arr[j];
                j -= step;
            }
            arr[j + step] = temp;
        }
    }
}

5.归并排序

归并排序是一种分治算法,它将一个待排序的序列分成两个子序列,分别对两个子序列进行排序,然后将两个已排序的子序列合并成一个有序序列。

算法步骤:

  1. 分解:将待排序的序列分解为两个子序列,直到每个子序列只包含一个元素。

  2. 解决:递归地对每个子序列进行排序。

  3. 合并:将两个已排序的子序列合并成一个有序序列。

代码实现:

public class MergeSort {
    // 归并排序算法
    public static void mergeSort(int[] arr, int left, int right) {
        if (left < right) {
            int mid = (left + right) / 2;
            // 分解成两个子序列并递归排序
            mergeSort(arr, left, mid);
            mergeSort(arr, mid + 1, right);
            // 合并已排序的两个子序列
            merge(arr, left, mid, right);
        }
    }
​
    // 合并两个已排序的子序列
    public static void merge(int[] arr, int left, int mid, int right) {
        // 计算左右子序列的长度
        int n1 = mid - left + 1;
        int n2 = right - mid;
​
        // 创建临时数组存储左右子序列的元素
        int[] L = new int[n1];
        int[] R = new int[n2];
​
        // 将元素复制到临时数组中
        for (int i = 0; i < n1; i++) {
            L[i] = arr[left + i];
        }
        for (int j = 0; j < n2; j++) {
            R[j] = arr[mid + 1 + j];
        }
​
        // 合并两个子序列
        int i = 0, j = 0, k = left;
        while (i < n1 && j < n2) {
            if (L[i] <= R[j]) {
                arr[k] = L[i];
                i++;
            } else {
                arr[k] = R[j];
                j++;
            }
            k++;
        }
​
        // 将左子序列剩余的元素复制到原始数组中
        while (i < n1) {
            arr[k] = L[i];
            i++;
            k++;
        }
​
        // 将右子序列剩余的元素复制到原始数组中
        while (j < n2) {
            arr[k] = R[j];
            j++;
            k++;
        }
    }
}

6.快速排序

快速排序通常明显比其他 Ο(nlogn) 算法更快,因为它的内部循环(inner loop)可以在大部分的架构上很有效率地被实现出来。使用分治法(Divide and conquer)策略来把一个串行(list)分为两个子串行(sub-lists)。

算法步骤:

  • 从数列中挑出一个元素,称为 "基准"(pivot)。

  • 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。

  • 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。

代码实现:

public class QuickSort implements IArraySort {
​
    @Override
    public int[] sort(int[] sourceArray) throws Exception {
        // 对 arr 进行拷贝,不改变参数内容
        int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);
​
        return quickSort(arr, 0, arr.length - 1);
    }
​
    private int[] quickSort(int[] arr, int left, int right) {
        if (left < right) {
            int partitionIndex = partition(arr, left, right);
            quickSort(arr, left, partitionIndex - 1);
            quickSort(arr, partitionIndex + 1, right);
        }
        return arr;
    }
​
    private int partition(int[] arr, int left, int right) {
        // 设定基准值(pivot)
        int pivot = left;
        int index = pivot + 1;
        for (int i = index; i <= right; i++) {
            if (arr[i] < arr[pivot]) {
                swap(arr, i, index);
                index++;
            }
        }
        swap(arr, pivot, index - 1);
        return index - 1;
    }
​
    private void swap(int[] arr, int i, int j) {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }
​
}

7.堆排序

堆排序(Heapsort)是指利用堆这种数据结构所设计的一种排序算法。堆积是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。堆排序可以说是一种利用堆的概念来排序的选择排序。分为两种方法:大顶堆:每个节点的值都大于或等于其子节点的值,在堆排序算法中用于升序排列;小顶堆:每个节点的值都小于或等于其子节点的值,在堆排序算法中用于降序排列。

算法步骤:

  • 创建一个堆 H[0……n-1]。

  • 把堆首(最大值)和堆尾互换。

  • 把堆的尺寸缩小 1,并调用 shift_down(0),目的是把新的数组顶端数据调整到相应位置。

  • 重复步骤 2,直到堆的尺寸为 1。

代码实现:

public class HeapSort implements IArraySort {
​
    @Override
    public int[] sort(int[] sourceArray) throws Exception {
        // 对 arr 进行拷贝,不改变参数内容
        int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);
​
        int len = arr.length;
​
        buildMaxHeap(arr, len);
​
        for (int i = len - 1; i > 0; i--) {
            swap(arr, 0, i);
            len--;
            heapify(arr, 0, len);
        }
        return arr;
    }
​
    private void buildMaxHeap(int[] arr, int len) {
        for (int i = (int) Math.floor(len / 2); i >= 0; i--) {
            heapify(arr, i, len);
        }
    }
​
    private void heapify(int[] arr, int i, int len) {
        int left = 2 * i + 1;
        int right = 2 * i + 2;
        int largest = i;
​
        if (left < len && arr[left] > arr[largest]) {
            largest = left;
        }
​
        if (right < len && arr[right] > arr[largest]) {
            largest = right;
        }
​
        if (largest != i) {
            swap(arr, i, largest);
            heapify(arr, largest, len);
        }
    }
​
    private void swap(int[] arr, int i, int j) {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }
​
}

8.桶排序

桶排序是一种分布式排序算法。基本思想是将要排序的数据分到有限数量的桶中,每个桶再分别进行排序(可以使用其他排序算法,如插入排序、快速排序等),最后将各个桶中的数据按顺序合并起来,得到最终的排序结果。

示意图:

代码实现:

public class BucketSort implements IArraySort {
​
    private static final InsertSort insertSort = new InsertSort();
​
    @Override
    public int[] sort(int[] sourceArray) throws Exception {
        // 对 arr 进行拷贝,不改变参数内容
        int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);
​
        return bucketSort(arr, 5);
    }
​
    private int[] bucketSort(int[] arr, int bucketSize) throws Exception {
        if (arr.length == 0) {
            return arr;
        }
​
        int minValue = arr[0];
        int maxValue = arr[0];
        for (int value : arr) {
            if (value < minValue) {
                minValue = value;
            } else if (value > maxValue) {
                maxValue = value;
            }
        }
​
        int bucketCount = (int) Math.floor((maxValue - minValue) / bucketSize) + 1;
        int[][] buckets = new int[bucketCount][0];
​
        // 利用映射函数将数据分配到各个桶中
        for (int i = 0; i < arr.length; i++) {
            int index = (int) Math.floor((arr[i] - minValue) / bucketSize);
            buckets[index] = arrAppend(buckets[index], arr[i]);
        }
​
        int arrIndex = 0;
        for (int[] bucket : buckets) {
            if (bucket.length <= 0) {
                continue;
            }
            // 对每个桶进行排序,这里使用了插入排序
            bucket = insertSort.sort(bucket);
            for (int value : bucket) {
                arr[arrIndex++] = value;
            }
        }
​
        return arr;
    }
​
    /**
     * 自动扩容,并保存数据
     *
     * @param arr
     * @param value
     */
    private int[] arrAppend(int[] arr, int value) {
        arr = Arrays.copyOf(arr, arr.length + 1);
        arr[arr.length - 1] = value;
        return arr;
    }
​
}

9.基数排序

基数排序是一种非比较型整数排序算法,其原理是将整数按位数切割成不同的数字,然后按每个位数分别比较。由于整数也可以表达字符串(比如名字或日期)和特定格式的浮点数,所以基数排序也不是只能使用于整数。

示意图:

代码:

/**
 * 基数排序
 * 考虑负数的情况还可以参考: https://code.i-harness.com/zh-CN/q/e98fa9
 */
public class RadixSort implements IArraySort {
​
    @Override
    public int[] sort(int[] sourceArray) throws Exception {
        // 对 arr 进行拷贝,不改变参数内容
        int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);
​
        int maxDigit = getMaxDigit(arr);
        return radixSort(arr, maxDigit);
    }
​
    /**
     * 获取最高位数
     */
    private int getMaxDigit(int[] arr) {
        int maxValue = getMaxValue(arr);
        return getNumLenght(maxValue);
    }
​
    private int getMaxValue(int[] arr) {
        int maxValue = arr[0];
        for (int value : arr) {
            if (maxValue < value) {
                maxValue = value;
            }
        }
        return maxValue;
    }
​
    protected int getNumLenght(long num) {
        if (num == 0) {
            return 1;
        }
        int lenght = 0;
        for (long temp = num; temp != 0; temp /= 10) {
            lenght++;
        }
        return lenght;
    }
​
    private int[] radixSort(int[] arr, int maxDigit) {
        int mod = 10;
        int dev = 1;
​
        for (int i = 0; i < maxDigit; i++, dev *= 10, mod *= 10) {
            // 考虑负数的情况,这里扩展一倍队列数,其中 [0-9]对应负数,[10-19]对应正数 (bucket + 10)
            int[][] counter = new int[mod * 2][0];
​
            for (int j = 0; j < arr.length; j++) {
                int bucket = ((arr[j] % mod) / dev) + mod;
                counter[bucket] = arrayAppend(counter[bucket], arr[j]);
            }
​
            int pos = 0;
            for (int[] bucket : counter) {
                for (int value : bucket) {
                    arr[pos++] = value;
                }
            }
        }
​
        return arr;
    }
​
    /**
     * 自动扩容,并保存数据
     *
     * @param arr
     * @param value
     */
    private int[] arrayAppend(int[] arr, int value) {
        arr = Arrays.copyOf(arr, arr.length + 1);
        arr[arr.length - 1] = value;
        return arr;
    }
}

10.计数排序

计数排序的核心在于将输入的数据值转化为键存储在额外开辟的数组空间中。作为一种线性时间复杂度的排序,计数排序要求输入的数据必须是有确定范围的整数。

算法步骤:

  • 找出待排序的数组中最大和最小的元素

  • 统计数组中每个值为i的元素出现的次数,存入数组C的第i项

  • 对所有的计数累加(从C中的第一个元素开始,每一项和前一项相加)

  • 反向填充目标数组:将每个元素i放在新数组的第C(i)项,每放一个元素就将C(i)减去1

代码实现:

public class CountingSort implements IArraySort {
​
    @Override
    public int[] sort(int[] sourceArray) throws Exception {
        // 对 arr 进行拷贝,不改变参数内容
        int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);
​
        int maxValue = getMaxValue(arr);
​
        return countingSort(arr, maxValue);
    }
​
    private int[] countingSort(int[] arr, int maxValue) {
        int bucketLen = maxValue + 1;
        int[] bucket = new int[bucketLen];
​
        for (int value : arr) {
            bucket[value]++;
        }
​
        int sortedIndex = 0;
        for (int j = 0; j < bucketLen; j++) {
            while (bucket[j] > 0) {
                arr[sortedIndex++] = j;
                bucket[j]--;
            }
        }
        return arr;
    }
​
    private int getMaxValue(int[] arr) {
        int maxValue = arr[0];
        for (int value : arr) {
            if (maxValue < value) {
                maxValue = value;
            }
        }
        return maxValue;
    }
​
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/612033.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

SpringCloud面试题

SpringCloud常见组件有哪些 注册中心组件&#xff1a;Eureka、Nacos 负载均衡组件&#xff1a;Ribbon 远程调用组件&#xff1a;OpenFeign 网关组件&#xff1a;Zuul、Gateway 服务保护组件&#xff1a;Hystrix、Sentinel 服务配置管理组件&#xff1a;SpringCloudConfig、Nac…

OpenCompass大模型评估

作业链接&#xff1a; Tutorial/opencompass/homework.md at camp2 InternLM/Tutorial GitHub 项目链接&#xff1a; GitHub - open-compass/opencompass: OpenCompass is an LLM evaluation platform, supporting a wide range of models (Llama3, Mistral, InternLM2,GPT-…

Docker快速搭建NAS服务——FileBrowser

Docker快速搭建NAS服务——FileBrowser 文章目录 前言FileBrowser的搭建docker-compose文件编写运行及访问 总结 前言 本文主要讲解如何使用docker在本地快速搭建NAS服务&#xff0c;这里主要写如下两种&#xff1a; FileBrowser1&#xff1a;是一个开源的Web文件管理器&…

【吊打面试官系列】Java高并发篇 - 为什么 wait(), notify()和 notifyAll ()必须在同步方法或者同步块中被调用?

大家好&#xff0c;我是锋哥。今天分享关于 【为什么 wait(), notify()和 notifyAll ()必须在同步方法或者同步块中被调用&#xff1f;】面试题&#xff0c;希望对大家有帮助&#xff1b; 为什么 wait(), notify()和 notifyAll ()必须在同步方法或者同步块中被调用&#xff1f;…

这3种深拷贝实现,你都知道吗?

目录&#xff1a; 1、JSON.parse 2、structuredClone 3、cloneDeep

【竞技宝jjb.lol】MSI:换线战术或将成为BLG命门

北京时间2024年5月10日,英雄联盟2024MSI季中赛继续进行,昨日迎来胜败分组赛首轮BLG对阵PSG。本以为这场比赛没有任何悬念,BLG将会非常轻松地击败PSG,没想到最终PSG两度扳平比分,BLG决胜局抗住压力才艰难取胜。虽然赢下了比赛,但BLG低迷的状态还是在比赛结束后遭到网友们的热议。…

超全MySQL锁机制介绍

前言 MySQL作为关系型数据库管理系统中的佼佼者&#xff0c;为了保证数据的一致性和完整性&#xff0c;在并发控制方面采用了锁机制。锁机制是数据库管理系统用于控制对共享资源的访问&#xff0c;避免多个事务同时修改同一数据造成的数据不一致问题。了解MySQL的锁机制对于数…

【组合博弈】介绍

本文为学习笔记&#xff0c;详细内容参考"Lessons in Play,Michael H. Albert Richard J. Nowakowski David Wolfe" 文章目录 组合博弈介绍(Combinatorial Games)DOMINEERING游戏组合游戏选手介绍Options博弈树&#xff08;game tree&#xff09; 组合博弈介绍(Combi…

*****水上飞机:继承,虚函数,虚继承

一题目 请设计以下航行器、飞机、船、水上飞机等 4 个类。 CRAFT 为航行器类&#xff0c;是公共基类&#xff0c;提供航行器的基本特性。包括&#xff1a; 一个保护数据成员&#xff1a;speed(速度)。 三个公有成员函数&#xff1a;构造函数(初始化速度)、析构函数和 Show 函数…

ASP.NET学生成绩管理系统

摘要 本系统依据开发要求主要应用于教育系统&#xff0c;完成对日常的教育工作中学生成绩档案的数字化管理。开发本系统可使学院教职员工减轻工作压力&#xff0c;比较系统地对教务、教学上的各项服务和信息进行管理&#xff0c;同时&#xff0c;可以减少劳动力的使用&#xf…

操作系统实战(三)(linux+C语言实现)

实验目的 加深对进程调度概念的理解&#xff0c;体验进程调度机制的功能&#xff0c;了解Linux系统中进程调度策略的使用方法。 练习进程调度算法的编程和调试技术。 实验说明 1.在linux系统中调度策略分为3种 SCHED_OTHER&#xff1a;默认的分时调度策略&#xff0c;值为0…

通俗的理解网关的概念的用途(四):什么是网关设备?(网络层面)

任何一台Windows XP操作系统之后的个人电脑、Linux操作系统电脑都可以简单的设置&#xff0c;就可以成为一台具备“网关”性质的设备&#xff0c;因为它们都直接内置了其中的实现程序。MacOS有没有就不知道&#xff0c;因为没用过。 简单的理解&#xff0c;就是运行了具备第二…

使用nmcli命令在Linux系统上配置各种网络(有线、无线、vlan、vxlan、路由、网桥等)

前言&#xff1a;原文在我的博客网站中&#xff0c;持续更新数通、系统方面的知识&#xff0c;欢迎来访&#xff01; 使用nmcli命令在Linux系统上配置各种网络&#xff08;有线、无线、vlan、vxlan、路由、网桥等&#xff09;https://myweb.myskillstree.cn/123.html 你是否会…

使用GitLab自带的CI/CD功能在远程服务器部署项目(三)

前置内容&#xff1a; 通过Docker Compose部署GitLab和GitLab Runner&#xff08;一&#xff09; 使用GitLab自带的CI/CD功能在本地部署项目&#xff08;二&#xff09; 目录 一、在GitLab服务器上生成私钥与公钥 二、将公钥拷贝到应用服务器上 三、将私钥给到Docker Exec…

Windows系统下通过nginx配置多项目

文章目录 前言大概思路实际操作记录&#xff1a;查看nginx 错误日志问下AI注意点&#xff1a; 当访问域名根路径时&#xff0c;重定向到/pc总结 前言 在windows电脑启动一个nginx 测试配置多前端项目&#xff0c;一个pc端&#xff08;vue3tsvite &#xff0c;history路由&…

Vue3专栏项目 -- 二、自定义From组件(下)

需求分析&#xff1a; 现在我们还需要一个整体的表单在单击某个按钮的时候可以循环的验证每个input的值&#xff0c;最后我们还需要有一个事件可以得到最后验证的结果&#xff0c;从而进行下一步的操作 如下&#xff0c;我们应该有一个form表单包裹着全部的input表单&#xf…

【C语言】整数和浮点数在内存中的存储

大家可能在学习的时候会经常疑惑数据在内存中是怎样存储的&#xff0c;今天用一篇博客给你讲清楚&#xff01;&#xff01;&#xff01;从此不再疑惑&#xff01;&#xff01;&#xff01; 文章目录 1. 整数在内存中的存储2. 大小端字节序和字节序判断2.1 什么是大小端2.2 为什…

[VulnHub靶机渗透] Hackademic: RTB1

&#x1f36c; 博主介绍&#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 hacker-routing &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【应急响应】 【Java、PHP】 【VulnHub靶场复现】【面试分析】 &#x1f389;点赞➕评论➕收…

day2_greedyIntervalsLRU/LFU

二、贪心算法之区间调度问题 0.计算一个区间集合中无重复的区间的最大数量(模板) public int intervalSchedule(int[][] intvs) {if (intvs.length 0) return 0;// 按 end 升序排序Arrays.sort(intvs, (a, b) -> Integer.compare(a[1], b[1]));// 至少有一个区间不相交in…