写点什么

详述 Java 中 sort 排序函数

作者:秋名山码民
  • 2022 年 6 月 04 日
  • 本文字数:1820 字

    阅读完需:约 6 分钟

前言

手写一个排序算法的效率是很慢的,当然这也不利于我们在比赛或者工程中的实战,如今几乎每个语言的标准库中都有排序算法,今天让我来给大家讲解一下 Java 语言中的 sort 排序

升序排序

Collections 类中的 sort 方法可以实现 List 接口的集合进行排序


public static void main(String[] args) {    // 定义含有5个元素的数组    double[] scores = new double[] { 78, 45, 85, 97, 87 };    System.out.println("排序前数组内容如下:");
// 对scores数组进行循环遍历 for (int i = 0; i < scores.length; i++) { System.out.print(scores[i] + "\t"); } System.out.println("\n排序后的数组内容如下:");
// 对数组进行排序 Arrays.sort(scores);
// 遍历排序后的数组 for (int j = 0; j < scores.length; j++) { System.out.print(scores[j] + "\t"); }}
复制代码

降序排序

Java 中降序排序有俩种方法(和 c++很类似,可以看我这篇博客):c++sort排序


  1. 利用 Collections.reverseOrder() 方法


public static void main(String[] args) {    Integer[] a = { 9, 8, 7, 2, 3, 4, 1, 0, 6, 5 };    // 数组类型为Integer    Arrays.sort(a, Collections.reverseOrder());    for (int arr : a) {        System.out.print(arr + " ");    }}
复制代码


  1. 实现 Comparator 接口的复写 compare() 方法


public class Test {    public static void main(String[] args) {        /*         * 注意,要想改变默认的排列顺序,不能使用基本类型(int,double,char)而要使用它们对应的类         */        Integer[] a = { 9, 8, 7, 2, 3, 4, 1, 0, 6, 5 };        // 定义一个自定义类MyComparator的对象        Comparator cmp = new MyComparator();        Arrays.sort(a, cmp);        for (int arr : a) {            System.out.print(arr + " ");        }    }}
// 实现Comparator接口class MyComparator implements Comparator<Integer> { @Override public int compare(Integer o1, Integer o2) { /* * 如果o1小于o2,我们就返回正值,如果o1大于o2我们就返回负值, 这样颠倒一下,就可以实现降序排序了,反之即可自定义升序排序了 */ return o2 - o1; }}
复制代码

排序原理

对 sort 方法如何排序感到好奇?


通常,在看有关算法书籍的时候,会发现都说有关数组的排序算法,而且使用的都是随机访问,但是我们知道数组的随机访问是很快的,链表的随机访问很慢!实际上,可以使用一种归并排序的方法对链表高效的排序,不过,Java 并不是这样做的,它是将所有元素转入一个数组,对数组进行排序,然后,将排好序 的序列复制回列表


事实上 Collections.sort 方法底层就是调用的 Arrays.sort 方法,而 Arrays.sort 使用了两种排序方法,快速排序和优化的归并排序。


快速排序(quick)主要是对那些基本类型数据(int, short, long 等)排序, 而归并排序(merge)用于对 Object 类型进行排序。使用不同类型的排序算法主要是由于快速排序是不稳定的,而归并排序是稳定的。这里的稳定是指比较相等的数据在排序之后仍然按照排序之前的前后顺序排列。对于基本数据类型,稳定性没有意义,而对于 Object 类型,稳定性是比较重要的,因为对象相等的判断可能只是判断关键属性,最好保持相等对象的非关键属性的顺序与排序前一致;另外一个原因是由于归并排序相对而言比较次数比快速排序少,移动(对象引用的移动)次数比快速排序多,而对于对象来说,比较一般比移动耗时。此外,对大数组排序。快速排序的 sort()采用递归实现,数组规模太大时会发生堆栈溢出,而归并排序 sort()采用非递归实现,不存在此问题。


sort()是根据需要排序的数组的长度进行区分的:


首先先判断需要排序的数据量是否大于 60。小于 60:使用插入排序,插入排序是稳定的大于 60 的数据量会根据数据类型选择排序方式:基本类型:使用快速排序。「因为基本类型不需要考虑稳定性」Object 类型:使用归并排序「因为归并排序具有稳定性」


注意:不管是快速排序还是归并排序。在二分的时候小于 60 的数据量依旧会使用插入排序


关于稳定性,我们用下面这个例子来说明:


假设,有一个已经按照姓名排序的员工列表,现在我们要按照工资进行再次的排序,如果俩个员工的工资又刚好相同怎么办?如果采用稳定的排序方法,将会保留按照姓名的排序,换句话说,我们最后得到的是一个先按照姓名排序,又按照工资排序的一个表

发布于: 16 分钟前阅读数: 5
用户头像

卷不死,就往…… 2021.10.19 加入

2019NOIP退役成员,华为云享专家,阿里云专家博主,csdn博主,努力进行算法分享,有问题欢迎私聊

评论

发布
暂无评论
详述Java中sort排序函数_算法_秋名山码民_InfoQ写作社区