之前看了这个方法,然后空了仔细看一下,收获还是挺多的,应该有bug,没有仔细测。
参考:https://blog.csdn.net/bruce_6/article/details/38299199讲得很清楚
package com.arraysort;
/**
* @author
* @date 2022/1/20
*/
public class ComparableTimeSortDemo {
public void sort(Object[] a, int first, int len){
assert a != null && first >= 0 && first <= len && len <= a.length;
int nRemaining = len - first;
if (nRemaining < 2)
return; // Arrays of size 0 and 1 are always sorted
// If array is small, do a "mini-TimSort" with no merges
if (nRemaining < 32) {
int initRunLen = countRunAndMakeAscending(a, first, len);
binarySort(a, first, len, first + initRunLen);
return;
}
//这下面感觉很复杂,不想写了,但是都差不多
}
/**
* 返回顺序的个数
* @param a 操作的数组
* @param first 起始位置
* @param len 结束位置
* @return 顺序的个数
*/
public int countRunAndMakeAscending(Object[] a, int first, int len){
int last = first + 1;
if(last==len){
return 1;
}
//如果是逆序compareTo,1.compareTo(2)<0。
if(((Comparable) a[last]).compareTo(a[first]) < 0){
//找到逆序的个数
while (last<len-1 && ((Comparable) a[++last]).compareTo(a[last]) < 0){
}
//弄成顺序
reverseRange(a,first,last);
}else{
while (last<len-1 && ((Comparable) a[++last]).compareTo(a[last]) > 0){
}
}
//顺序的个数
return last-first;
}
/**
* 交换顺序
* 输入[1,2,3]输出[3,2,1]
* @param a 数组
* @param first 起始位置
* @param len 长度
*/
public void reverseRange(Object[] a, int first, int len){
//数组最后一个元素
len--;
while ( first < len){
Object c = a[first];
a[first] = a[len];
a[len] = c;
first++;
len--;
}
}
/**
* 二分排序,往有序的数组里面插入后面的元素
* @param a 数组
* @param first 起始位置
* @param len 结束位置
* @param start 插入数据起始位置
*/
void binarySort(Object[] a, int first, int len,int start){
assert first<len && first<=start && start<=len;
if(first==start){
start++;
}
for(;start<len;start++){
Comparable cpa = (Comparable)a[start];
int left = first;
int right = start;
//找到刚好比cpa大的位置,此时left==right
while (left < right){
int mid = left + right >> 1;
if(cpa.compareTo(a[mid])<0){
right = mid;
}else {
left = mid + 1;
}
}
//后移个数
int n = start - left;
//a数组从left位置起(是包括left的),复制到left+1,一共复制n个数字。
//源码这里判断了如果是后面两位就直接移,我这里图方便
System.arraycopy(a, left, a, left + 1, n);
//此时腾出来一个空位
a[left] = cpa;
}
}
}