归并排序

归并排序原理:将数组二分,然后对二分后的数组继续使用归并排序...当分解后数组元数足够小时(为1),说明每个数组已经排序好,然后将二分的数组通过某个算法合并成已经排好序的数组,直至整个数组都排序好序。

 

时间复杂度:最优O(n),最坏O(nlogn),平均O(nlogn)

 

归并排序jdk源码优化方案:

1. 当分解后的数组元素个数小于7时,改用插入排序

2. 当二分后的已经排好序的两个数组,左边的最大值小于等于右边最小值时,不需要再合并

3. 复制一份源数组,在归并两个已排序数组时,只要将源数据按顺序移到目标数组中,可以避免在同一个数组整体移动产生开销,达到线性时间,以空间换时间

 

public static final int INSERTIONSORT_THRESHOLD = 7;

 

public static <T extends Comparable<T>> int compare(T a, T b) {
    if (a == null){
        return b == null ? 0 : -1;
    }
    if (b == null){
        return 1;
    }
    return a.compareTo(b);
}

 

/**
 * @description 归并排序
 * @param src 待排数组
 * @param dest 排序后的数组
 * @param offset 开始位置
 * @param end 结束位置
 */
public static <T extends Comparable<T>> void mergeSort(T[] src, T[] dest, int offset, int end) {
    int size = end - offset;
    //当数组元素个数小于7时,插入排序性能最好
    if (size < INSERTIONSORT_THRESHOLD) {
        insertSort(dest, offset, end);
        return;
    }
    int mid = (offset + end) >>> 1;
    //递归将左半部分未排序的数据,排好序后放入源数组中
    mergeSort(dest, src, offset, mid);
    //递归将右半部分未排序的数据,排好序后放入源数组中
    mergeSort(dest, src, mid, end);
    //左边最大数比右边最小数小,说明数组已经排好序,直接拷贝到目标数组中
    if (compare(src[mid - 1], src[mid]) <= 0) {
        System.arraycopy(src, offset, dest, offset, size);
        return;
    }
    //按顺序将源数据拷贝到目标数组中
    for (int i = offset, p = i, q = mid; i < end; ++i) {
        if (q >= end || p < mid && compare(src[p], src[q]) <= 0) {
            dest[i] = src[p++];
        } else {
            dest[i] = src[q++];
        }
    }
}

/**
 * @description 归并排序
 * @param data
 */
public static <T extends Comparable<T>> void mergeSort(T[] data) {
    if (data != null && data.length > 1){
        //复制一份数组做交换空间
        T[] src = (T[]) data.clone();
        mergeSort(src, data, 0, data.length);
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值