經常使用Collections.sort(List<T> list, Comparator<? super T> c)來排序,jdk怎麼實現的,1.7有幾個方法
mergeSort()使用歸併排序
TimSort.sort()使用二分插入排序,和優化後歸併排序
//java.util.Arrays 1.7
//歸併排序,把數組拆分,如果需要子數組繼續拆分(遞歸),拆成小數組比較,然後依次往上合併
private static void mergeSort(Object[] src,
Object[] dest,
int low,
int high,
int off) {
int length = high - low;
// Insertion sort on smallest arrays
// 插入排序
if (length < INSERTIONSORT_THRESHOLD) {
for (int i=low; i<high; i++)
for (int j=i; j>low &&
((Comparable) dest[j-1]).compareTo(dest[j])>0; j--)
swap(dest, j, j-1);
return;
}
// Recursively sort halves of dest into src
int destLow = low;
int destHigh = high;
low += off;
high += off;
int mid = (low + high) >>> 1;
mergeSort(dest, src, low, mid, -off);
mergeSort(dest, src, mid, high, -off);
// If list is already sorted, just copy from src to dest. This is an
// optimization that results in faster sorts for nearly ordered lists.
//left最大的小於right最小的,已經排好
if (((Comparable)src[mid-1]).compareTo(src[mid]) <= 0) {
System.arraycopy(src, low, dest, destLow, length);
return;
}
// Merge sorted halves (now in src) into dest
//每次取 兩個組合的最小值比較,最小的放到dest[i]
for(int i = destLow, p = low, q = mid; i < destHigh; i++) {
if (q >= high || p < mid && ((Comparable)src[p]).compareTo(src[q])<=0)
dest[i] = src[p++];
else
dest[i] = src[q++];
}
}
//java.util.TimSort<T>
//二分插入排序,插入排序基礎上,使用二分法快速找到,新元素在有序數組位置,移動數組,插入新元素
private static <T> void binarySort(T[] a, int lo, int hi, int start,
Comparator<? super T> c) {
assert lo <= start && start <= hi;
if (start == lo)
start++;
for ( ; start < hi; start++) {
T pivot = a[start];
// Set left (and right) to the index where a[start] (pivot) belongs
int left = lo;
int right = start;
assert left <= right;
/*
* Invariants:
* pivot >= all in [lo, left).
* pivot < all in [right, start).
*/
//二分法定位
while (left < right) {
int mid = (left + right) >>> 1;
if (c.compare(pivot, a[mid]) < 0)
right = mid;
else
left = mid + 1;
}
assert left == right;
/*
* The invariants still hold: pivot >= all in [lo, left) and
* pivot < all in [left, start), so pivot belongs at left. Note
* that if there are elements equal to pivot, left points to the
* first slot after them -- that's why this sort is stable.
* Slide elements over to make room for pivot.
*/
int n = start - left; // The number of elements to move
// Switch is just an optimization for arraycopy in default case
switch (n) {
case 2: a[left + 2] = a[left + 1];//位置在自己位置-2處,需要移動兩次,注沒有break
case 1: a[left + 1] = a[left];//位置在自己位置-1處,移動一次
break;
default: System.arraycopy(a, left, a, left + 1, n);//更多次情況,使用arraycopy函數,然後插入新元素
}
a[left] = pivot;
}
}
快排
package sort;
public class Test1 {
public static void quickSort(int[] a,int low,int high){
if(low >= high) return;
int po = low;
int key = a[low];
for(int i=low+1;i<=high;i++){
if(a[i] < key){
if((i-po) == 1){
a[po] = a[i];
a[i] = key;
po = i;
}else{
//po - i
key = a[i];
for(int j=i;j>po;j--){
a[j] = a[j-1];
}
a[po] = key;
po = po +1;
key = a[po];
}
}
}
quickSort(a,low,po-1);
quickSort(a,po+1,high);
}
public static void main(String[] args) {
int[] a = {1,9,0,2,8,3,-7,11,-23,66,6};
quickSort(a,0,a.length-1);
for (int i : a) {
System.out.print(i+",");
}
}
}
快排得到數組第k大值
package sort;
public class Test2 {
public static int quickSort(int[] a,int low,int high,int k){
int index = a.length - k;
int po = low;
int key = a[low];
for(int i=low+1;i<=high;i++){
if(a[i] < key){
if((i-po) == 1){
a[po] = a[i];
a[i] = key;
po = i;
}else{
//po - i
key = a[i];
for(int j=i;j>po;j--){
a[j] = a[j-1];
}
a[po] = key;
po = po +1;
key = a[po];
}
}
}
System.out.println("------"+key);
for (int i : a) {
System.out.print(i+",");
}
System.out.println();
System.out.println("------"+po);
System.out.println();
if(po == index){
return a[po];
}else if(po < index){
//right
return quickSort(a,po+1,high,k);
}else{
return quickSort(a,low,po-1,k);
}
}
public static void main(String[] args) {
int[] a = {1,9,0,2,8,3,-7,11,-23,66,6};
//-23,-7,0,1,2,3,6,8,9,11,66,
System.out.println("result: "+quickSort(a,0,a.length-1,2));
for (int i : a) {
System.out.print(i+",");
}
}
}