您的位置:首页 > 其它

Collections.sort() 排序算法 源码简介

2017-05-23 12:01 295 查看
版本1.70 点击进来的代码是这样的:   

public static <T> void sort(List<T> list, Comparator<? super T> c) {
Object[] a = list.toArray();
Arrays.sort(a, (Comparator)c);
ListIterator i = list.listIterator();
for (int j=0; j<a.length; j++) {
i.next();
i.set(a[j]);
}
}


简单说下注释,稳定的、自适应的n lg(n)的。

源码里 实际调用的是数组的排序!!!   

public static <T> void sort(T[] a, Comparator<? super T> c) {
if (LegacyMergeSort.userRequested)
legacyMergeSort(a, c);
else
TimSort.sort(a, c);
}


在说下这里的注释,LegacyMergeSort.userRequested 会在之后的版本废弃掉,至少先不用管了,我们专心看TimSort。

点击去

static <T> void sort(T[] a, Comparator<? super T> c) {
sort(a, 0, a.length, c);
}


再进去,呵呵哒,和python有一腿···

static <T> void sort(T[] a, int lo, int hi, Comparator<? super T> c) {
if (c == null) {
Arrays.sort(a, lo, hi);
return;
}

rangeCheck(a.length, lo, hi);
int nRemaining  = hi - lo;
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 < MIN_MERGE) {
int initRunLen = countRunAndMakeAscending(a, lo, hi, c);
binarySort(a, lo, hi, lo + initRunLen, c);
return;
}

/**
* March over the array once, left to right, finding natural runs,
* extending short natural runs to minRun elements, and merging runs
* to maintain stack invariant.
*/
TimSort<T> ts = new TimSort<>(a, c);
int minRun = minRunLength(nRemaining);
do {
// Identify next run
int runLen = countRunAndMakeAscending(a, lo, hi, c);

// If run is short, extend to min(minRun, nRemaining)
if (runLen < minRun) {
int force = nRemaining <= minRun ? nRemaining : minRun;
binarySort(a, lo, lo + force, lo + runLen, c);
runLen = force;
}

// Push run onto pending-run stack, and maybe merge
ts.pushRun(lo, runLen);
ts.mergeCollapse();

// Advance to find next run
lo += runLen;
nRemaining -= runLen;
} while (nRemaining != 0);

// Merge all remaining runs to complete sort
assert lo == hi;
ts.mergeForceCollapse();
assert ts.stackSize == 1;
}


继续看,大致的意思是TimSort 本来 属于mergeSort的一种改进,引入binarySort进行子数组的排序,实现优化(原来的子数组排序是采用的选择排序),每次进行子数组合并的时候会进行一些特殊的处理来进行对一些特殊情况的优化。

总言之,这是个稳定、 时间复杂度是O(nlogn)   , 空间复杂度是O(n) 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: