十大经典排序算法之归并排序(Java语言)

归并排序和快排一样使用的是分治的思想,所以也可以提供很好的性能,但是归并可以提供比快排更稳定的性能,以及归并排序本身是稳定的,所以被很多语言用在对象排序方式上,java的Arrays.sort方法的对象排序用的就是归并排序的一种

扩展:在jdk1.8之后,Arrays.sort的对象排序在某个阈值下使用的二分插入排序,当元素个数大于阈值的时候使用的是一种改进的归并排序TimSort,中文名叫多路归并
Arrays.sort的基本类型用的是一种改进的快排

我这里以从小到大排序为例:
基本的归并排序是将待排数组拆成两等分的子数组,然后再将子数组拆成两等分的孙子数组,直到拆成数组中只有一个元素的时候停止拆分,然后再进行两两合并,合并的时候同时遍历两个子数组的元素并进行比较,每次将两个数组中较小的元素弹出并按顺序放回原数组,直到其中一个数组没有元素了,已知两个子数组已经各自有序了,那么另外一个子数组剩下的元素一定都比已经填入原数组的元素大,此时就不再需要比较,直接挨个按顺序填回原数组就可以了,合并完成后的数组就是有序数组,然后再将这个数组合并到更大的数组中,直到整个数组全部合并完毕,排序完成

归并在的数据量下拥有比快排更稳定的性能

中文名称英文名称平均时间复杂度最坏时间复杂度最好时间复杂度空间复杂度稳定性
归并排序Mergen*lognn*lognn*lognn稳定
private static void merge(int arr[], int left, int mid, int right){
    //我们将原数组需要合并的部分直接合并到这个数组,然后再将这个数组覆盖回去,这样只创建一个临时数组就够用了
    int[] tempArr = new int[right - left + 1];
    //l是第一个子数组的下标,r是第二个子数组的下标,i是临时数组的下标
    int l = left,r = mid,i = 0;
    //将两个子数组的元素按顺序插入到临时数组中
    while (l < mid && r <= right){
        if(arr[l] <= arr[r]){
            tempArr[i] = arr[l];
            i++;
            l++;
        }else{
            tempArr[i] = arr[r];
            i++;
            r++;
        }
    }
    //如果有哪个数组仍然有元素没有插入到临时数组中,那么直接全部插入
    if(l < mid){
        for (int j = l; j < mid; j++,i++){
            tempArr[i] = arr[j];
        }
    }
    if(r <= right){
        for (int j = r; j <= right; j++,i++){
            tempArr[i] = arr[j];
        }
    }
    //把排好序的临时数组覆盖回原数组对应的位置
    for (int j = 0; j < tempArr.length && left <= right; j++,left++) {
        arr[left] = tempArr[j];
    }
}

private static void sort(int arr[], int left, int right){
    if(left==right){
        return;
    }
    //拆拆拆,然后递归递归递归
    int mid = (left + right) / 2;
    sort(arr, left, mid);
    sort(arr, mid+1, right);
    merge(arr, left, mid+1, right);
}

public static void sort(int arr[]){
    sort(arr, 0, arr.length - 1);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值