Arrays.sort底层排序算法

本文详细探讨了Java中Arrays.sort方法的底层实现。在小数组情况下,它使用快速排序,而微小数组则采用插入排序。当数组长度超过一定阈值(286)时,将使用归并排序。在归并排序前,会先检查数组是否高度无序,如果是,则转而使用快速排序。整个过程涉及到多种排序策略的选择,旨在平衡效率和稳定性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Arrays.sort底层排序算法

一直以来,我都认为Java内部排序的算法是快速排序。直到有一天,我在面经上看到了有一道这样子的问题。我才发觉,事情远没有我想的那么简单。
底层排序算法又根据目标数组分为了好几种排序方法。

  • 归并排序为非递归写法(应该是为了避免递归次数过多引起的堆栈溢出)
  • 快排又分为两种,双基准三路快排

int、long类型

点进我们的底层源码来,我们就会看到一行注释,说的就是在小数组的情况下,使用快速排序。

	// Use Quicksort on small arrays
	if (right - left < QUICKSORT_THRESHOLD) {
	    sort(a, left, right, true);
	    return;
	}

但是!我们在点进这个sort后,就又又又会发现又有一行注释,说的是在微小数组里,使用插入排序。

	// Use insertion sort on tiny arrays
	if (length < INSERTION_SORT_THRESHOLD) {
	    if (leftmost) {

那么两种数组是根据多大的长度来区分的呢
数组长度小于int QUICKSORT_THRESHOLD = 286 286这个阈值时,且大于int INSERTION_SORT_THRESHOLD = 47 47是,采用的就是快速排序了,小于47就采用插入排序。
当然了,这两个排序就不想多说了,大家应该也都非常清楚了。
重点讲一下大于286时,是采用哪一种排序呢?
长度大于286后,就会采用归并排序了。
可是在采用归并排序之前,底层还是会遍历整个数组,为接下来的排序做好准备。

	/*
	 * Index run[i] is the start of i-th run
	 * (ascending or descending sequence).
	 */
	int[] run = new int[MAX_RUN_COUNT + 1];
	int count = 0; run[0] = left;
	
	// Check if the array is nearly sorted
	for (int k = left; k < right; run[count] = k) {
	    if (a[k] < a[k + 1]) { // ascending
	        while (++k <= right && a[k - 1] <= a[k]);
	    } else if (a[k] > a[k + 1]) { // descending
	        while (++k <= right && a[k - 1] >= a[k]);
	        for (int lo = run[count] - 1, hi = k; ++lo < --hi; ) {
	            int t = a[lo]; a[lo] = a[hi]; a[hi] = t;
	        }
	    } else { // equal
	        for (int m = MAX_RUN_LENGTH; ++k <= right && a[k - 1] == a[k]; ) {
	            if (--m == 0) {
	                sort(a, left, right, true);
	                return;
	            }
	        }
	    }
	
	    /*
	     * The array is not highly structured,
	     * use Quicksort instead of merge sort.
	     */
	    if (++count == MAX_RUN_COUNT) {
	        sort(a, left, right, true);
	        return;
	    }
	}

上面的逻辑主要就是,在遍历整个数组的同时,将一段无序的数组给排序,同时将一个标志的值给+1。要是这个值在遍历数组的过程中超出int MAX_RUN_COUNT = 67的话,就代表着整个数组是高度无序的,更加适合快排,否则就进行最终的归并排序了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值