1. 程式人生 > >集合排序

集合排序

過程 pub urn extend link 面試官 數組 子序列 ons

摘要,面試中問集合的時候是非常多的,最簡單的莫過於ArrayList 和 LinkList區別了,難一點的可能會問集合中某一個方法的實現細節。
場景對話:面試官:問你一個關於集合的問題,ArrayList是有序的麽?
我:不是
面試官:那怎麽對它進行排序呢?
我:可以使用Collections.sort()方法,這個方法默認是升序的,如果要降序排列可以重寫Compare方法或者使用reverseOrder();

如下:List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
Collections.sort(list);
Collections.sort(list,Collections.<Integer>reverseOrder()); or
Collections.sort(list, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
//降序
return o2.compareTo(o1);
}
});
面試官:那你知道他的底層是怎樣實現的嗎?
我:(這好像以前沒事的時候看過一眼,不過沒太在意) 額...這個..額 以前有看過,讓我想想
(半分鐘後)好吧 ,不太記得具體的實現的過程了,但是記得是基於歸並排序實現的。
面試官:那你回去再看看吧,下一個問題...(雞雞)
源碼:

技術分享

(這裏可以看到 Collections.sort()是基於Arrays.sort()實現的 )

Array.sort()

技術分享

TimSort.sort()

static <T> void sort(T[] a, int lo, int hi, Comparator<? super T> c,
T[] work, int workBase, int workLen) {
assert c != null && a != null && lo >= 0 && lo <= hi && hi <= a.length;

int nRemaining = hi - lo;
if (nRemaining < 2)
return; // array的大小為0或者1就不用排了

// 當數組大小小於MIN_MERGE(32)的時候,就用一個"mini-TimSort"的方法排序,jdk1.7新加

if (nRemaining < MIN_MERGE) {
int initRunLen = countRunAndMakeAscending(a, lo, hi, c);
binarySort(a, lo, hi, lo + initRunLen, c);
return;
}

//先掃描一次array,找到已經排好的序列,然後再用剛才的mini-TimSort,然後合並,這就是TimSort的核心思想
TimSort<T> ts = new TimSort<>(a, c, work, workBase, workLen);
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;
}
 Array.sort()底層實現都是TimSort實現的,這是jdk1.7新增的,以前是歸並排序。TimSort算法就是找到已經排好序數據的子序列,然後對剩余部分排序,然後合並起來

集合排序