Java Arrays.sort()如何实现对int类型数组倒序排序

 更新时间:2023年08月21日 09:59:02   作者:mp-ui  
这篇文章主要介绍了Java Arrays.sort()如何实现对int类型数组倒序排序问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

Java Arrays.sort()实现对int类型数组倒序排序

Java的Arrays.sort()仅支持对引用数据类型进行自定义排序,如果是基本数据类型(如int类型),将无法使用Comparator进行自定义排序。

可以使用下面的方法来实现

  • 1.手动实现排序算法。
  • 2.先排序再reverse
int[] nums = new int[]{1,6,4,55,61,3,5,8,4,2,8,15,61,33};
	Arrays.sort(nums);
	for (int i = 0; i < nums.length/2; i++) {
	    int temp = nums[i];
	    nums[i] = nums[nums.length - 1 - i];
	    nums[nums.length - 1 - i] = temp;
	}
	System.out.println(Arrays.toString(nums));
  • 3.转换成Integer[]
    int[] nums = new int[]{1,6,4,55,61,3,5,8,4,2,8,15,61,33};
    Integer[] temp = new Integer[nums.length];
    for (int i = 0; i < temp.length; i++) {
        temp[i] = nums[i];
    }
    Arrays.sort(temp,(i,j)->(j-i));
    for (int i = 0; i < nums.length; i++) {
        nums[i] = temp[i];
    }
    System.out.println(Arrays.toString(nums));

Arrays.sort()用的是什么排序算法?怎么优化?

Arrays.sort()用的是快速排序算法。相信大家对于这个都是了解的。

算法的思想

选择基准将数组一分为二,基准前面的比基准小,基准后面的比基准大,之后分别对这两部分继续之前的操作,已达到整个数组有序的目的。

算法内容描述

  • 先选择一个基准,指向数组开始的指针start和指向数组结束的指针end;
  • 当start小于end的时候,如果基准的值小于end指向数组的值时,end往前移动;
  • 当基准的值不在小于end指向数组的值的时候,交换两个指针指向的数组的值;
  • 然后当基准的值大于start指向数组的值的时候,start往后移动;
  • 当基准的值不大于start指向数组的值的时候,交换两个指针指向的数组的值;
  • 返回基准的位置并进行递归操作完成排序。

代码如下:

public class Test2 {
    public static void swap(int[] arr, int j, int i){
        int temp = arr[j];
        arr[j] = arr[i];
        arr[i] = temp;
    }
    public static int partition(int arr[], int start, int end){
        assert(null != arr);
        int temp = arr[start];
        while(start < end){
            while(temp < arr[end] && start < end){
                end--;
            }
            swap(arr, start, end);
            while(temp > arr[start] && start < end){
                start++;
            }
            swap(arr, start, end);
        }
        System.out.println(Arrays.toString(arr) + "   " +  start);
        return start;
    }
    public static void partitionSort(int arr[], int start, int end){
        assert(null != arr);
        if(start < end){
            int midd = partition(arr, start, end);
            partitionSort(arr, start, midd - 1);
            partitionSort(arr, midd + 1, end);
        }
    }
    public static void main(String[] args) {
        int arr[] = {9,1,5,8,3,7,4,6,2};  
        Test2.partitionSort(arr, 0, arr.length - 1);
        System.out.println(Arrays.toString(arr));
    }
}

执行结果:

[2, 1, 5, 8, 3, 7, 4, 6, 9] 8
[1, 2, 5, 8, 3, 7, 4, 6, 9] 1
[1, 2, 4, 3, 5, 7, 8, 6, 9] 4
[1, 2, 3, 4, 5, 7, 8, 6, 9] 3
[1, 2, 3, 4, 5, 6, 7, 8, 9] 6
[1, 2, 3, 4, 5, 6, 7, 8, 9]

快速排序的优化

①优化基准的选择

上面的程序选择的基准是数组起始位置,但是跟明显,我们并没有达到想要的理想结果将数组划分为两部分,进行递归操作;

所以就有了三数取中法来选取基准,即取三个关键字先进行排序,将中间数作为基准,一般去开始,结束,和中间;

当然也可以随机选取;其实还有一种九数取中法,这里就不详细介绍了,有兴趣的可以自己了解一下。

下面是三数取中法的代码:

public void medianOfThree(int[] arr, int start, int end){
        int m = start + (end - start) / 2;
        if(arr[start] > arr[end]){
            swap(arr, start, end);
        }
        if(arr[m] > arr[end]){
            swap(arr, end, m);
        }
        if(arr[m] > arr[start]){
            swap(arr, m, start);
        }
    }

②优化不必要的交换

首先我们通过上面的代码很容易发现在交换的过程中,有许多部分是没必要交换的,于是我们通过赋值替代交换来省去没必要的交换;

代码如下:

public int partition3(int arr[], int start, int end){
        assert(null != arr);
        medianOfThree(arr, start, end);
        int temp = arr[start];
        while(start < end){
            while(temp < arr[end] && start < end){
                end--;
            }
            arr[start] = arr[end];
            while(temp > arr[start] && start < end){
                start++;
            }
            arr[end] = arr[start];
        }
        arr[start] = temp;
        System.out.println(Arrays.toString(arr) + "   " +  start);
        return start;
    }

③优化小数组时的排序方案

一般对于小数组排序,我们需要选择插入排序,因为插入排序是简单排序性能最高的。所以我们做如下修改:

public void partitionSort4(int arr[], int start, int end){
        assert(null != arr);
        if((end - start) > INSERT_SORT){
            int midd = partition3(arr, start, end);
            partitionSort3(arr, start, midd - 1);
            partitionSort3(arr, midd + 1, end);
        }else{
            insertSort(arr);
        }
    }

其中,INSERT_SORT选择的大小众说纷纭,自我觉得在海量数据面前,选择20跟选择7没有太大的差异吧。(这话如果有误,望大家批评指正)

④优化递归操作

我们都知道递归的额外花销还是很大的,减少递归可以大大提高性能,故此做如下修改:

 public void partitionSort5(int arr[], int start, int end){
        assert(null != arr);
        int midd;
        if((end - start) > INSERT_SORT){
            while(start < end){
                midd = partition3(arr, start, end);
                partitionSort5(arr, start, midd - 1);
                start = midd + 1;
            }
        }else{
            insertSort(arr);
        }
    }

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • java连接MySQl数据库实例代码

    java连接MySQl数据库实例代码

    这篇文章介绍了java连接MySQl数据库实例代码,有需要的朋友可以参考一下
    2013-10-10
  • Spring项目XML文件使用小结

    Spring项目XML文件使用小结

    这篇文章主要介绍了Spring项目XML文件使用常见介绍,主要包括项目pom文件,项目初始IOC容器及项目需要自动装配的代码详解,本文通过实例代码给大家介绍的非常详细,需要的朋友可以参考下
    2022-07-07
  • JDK源码之PriorityQueue解析

    JDK源码之PriorityQueue解析

    这篇文章主要为大家详细介绍了JDK源码之PriorityQueue,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-04-04
  • 解决Springboot中Feignclient调用时版本问题

    解决Springboot中Feignclient调用时版本问题

    这篇文章主要介绍了解决Springboot中Feign client调用时版本问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-03-03
  • java实现动态验证码

    java实现动态验证码

    这篇文章主要为大家详细介绍了java实现动态验证码,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-03-03
  • QueryWrapper中or的使用技巧分享

    QueryWrapper中or的使用技巧分享

    在日常的开发工作中,处理数据库查询是一个非常常见的任务,尤其是当我们需要在复杂条件下筛选数据时,如何编写高效、简洁且可维护的查询逻辑显得尤为重要,本文给大家介绍了QueryWrapper中or的使用技巧,需要的朋友可以参考下
    2024-10-10
  • 使用SpringBoot 配置Oracle和H2双数据源及问题

    使用SpringBoot 配置Oracle和H2双数据源及问题

    这篇文章主要介绍了使用SpringBoot 配置Oracle和H2双数据源及问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-11-11
  • Java实现爬虫

    Java实现爬虫

    这篇文章介绍了Java实现爬虫的方法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-01-01
  • Java大文件分片上传超详细教程(minio版)

    Java大文件分片上传超详细教程(minio版)

    Minio是一个开源的分布式对象存储系统,它允许用户在存储服务上存储和检索数据,下面这篇文章主要给大家介绍了关于Java大文件分片上传(minio版)的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2024-08-08
  • Spring Security安全框架之记住我功能

    Spring Security安全框架之记住我功能

    这篇文章主要介绍了Spring Security安全框架之记住我,本次就来探究如何实现这种自动登录、记住我的功能,通过实例代码图文相结合给大家介绍的非常详细,需要的朋友可以参考下
    2022-02-02

最新评论