归并、二分插入排序

来源:互联网 发布:阿里云邮箱iphone7 编辑:程序博客网 时间:2024/06/18 08:38

经常使用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;        }    }



0 0
原创粉丝点击