歸併、二分插入排序、快速排序

經常使用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+",");
        }
    }

}


發佈了68 篇原創文章 · 獲贊 9 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章