看源碼時專門瞄了下排序算法,跟著學(xué)一下。JDK的排序是 插入排序、快排揉一起的,先來學(xué)下插入排序。在JDK中當待排序的元素個數(shù)小于 ** 47 ** 時使用插入排序。JDK源碼類:DualPivotQuicksort.java
本文地址:http://www.lxweimin.com/p/98539ba3fd86
- JDK中,leftmost為true時使用的是傳統(tǒng)的插入排序(跟下面代碼大同小異)
主要思想是:從i=2起直至i=n為止,依次將data[i]插入當前的有序區(qū)data[1..i-1]中。最快O(n),最壞O(n*n)
public static void sort(int[] array) {
int j, target;
for (int i = 1; i < array.length; i++) {
j = i;
target = array[i];
while (j > 0 && target < array[j - 1]) {
array[j] = array[j - 1];
j--;
}
array[j] = target;
}
}
- JDK中,leftmost為false時使用的是成對插入排序。
主要思想跟上面差不多,只不過一次拿兩個元素,先用其中一個較大的元素向前遍歷插入,然后再用較小的元素繼續(xù)向前遍歷插入,這樣較小的元素不必再次走一遍較大元素走過的路。對于元素個數(shù)為奇數(shù)的情況,最后一個元素單獨走一次插入排序即可。(JDK的跟這個有點區(qū)別)
JDK中的寫法不能直接拿來使用,改寫了一下。
public static void pairSort(int[] array) {
// 參數(shù)檢測
if (array == null || array.length < 2) {
return;
}
int right = array.length;
// 如果元素個數(shù)為奇數(shù),則數(shù)組長度 - 1
boolean adjust = false;
if (right % 2 == 1) {
adjust = true;
--right;
}
// 處理前兩個元素
if (array[0] > array[1]) {
int temp = array[0];
array[0] = array[1];
array[1] = temp;
}
// 排序,k = i - 1
for (int i = 2, k = 1; i < right; i += 2, k = i - 1) {
// 取值并保證 low < high
int low = array[i], high = array[i + 1];
if (low > high) {
low = high;
high = array[i];
}
// 插入較大的值
while (k >= 0 && high < array[k]) {
array[k + 2] = array[k];
k--;
}
array[k + 2] = high;
// 插入較小的值
while (k >= 0 && low < array[k]) {
array[k + 1] = array[k];
k--;
}
array[k + 1] = low;
}
// 處理最后一個元素
if (adjust) {
int begin = array.length - 1;
int value = array[begin];
while (--begin >= 0 && array[begin] > value) {
array[begin + 1] = array[begin];
}
array[begin + 1] = value;
}
}
經(jīng)測試,確實比傳統(tǒng)的插入排序要快,快多少跟數(shù)組元素中的數(shù)據(jù)有關(guān)。