java 实现归并排序

https://mp.csdn.net/console/editor/html/108763772 这篇文章实现了插入排序

插入排序相对比较简单也好理解,但是插入排序的时间复杂是很高的 O(n^2)

所以需要对插入排序进行优化,这里我们使用归并排序来进行优化

归并排序

通过二分的思想将数组元素拆分到只剩一个为止,在对我们的元素进行合并处理,合并的时候需要比较数组中的元素大小

时间复杂度:O(n log n)   稳定性:稳定

图解

/**以数组 int [] data = {6,5,3,7,8,2,3,1}; 为例  归并排序图解

*                                       { 6, 5, 3, 7, 8, 2, 3, 1}
* 拆分一次                   { 6, 5, 3, 7}          ↓            { 8, 2, 3, 1,}
* 拆分二次             { 6, 5}           { 3, 7}    ↓      { 8, 2}            { 3, 1}
* 拆分三次           {6}     {5}       {3}     {7}  ↓    {8}     {2}        {3}     {1}
* 合并一次             { 5, 6}           { 3, 7}    ↓      { 2, 8}            { 1, 3}
* 合并二次                   { 3, 5, 6, 7}          ↓            { 1, 2, 3, 8}
* 合并三次                               { 1, 2, 3, 3, 5, 6, 7, 8}
*/

代码实现

    public static void margeSort(int [] arr){
        if(arr == null || arr.length < 2) return;
        //通过递归的方式对数组进行拆分
        splitArray(arr,0,arr.length - 1);
    }

    public static void splitArray(int [] arr, int start, int end){
        if(start < end){
            //每次拆分都将数组平均分成两段
            int middle = (start + end) / 2;
            splitArray(arr,start,middle);
            splitArray(arr,middle + 1,end);
            //数组拆分完之后需要进行合并
            margeArray(arr,start,middle,end);
        }
    }

    public static void margeArray(int [] arr, int start, int middle, int end){
        //声明一个临时数组用来存放排好序的临时数据,方便理解和降低代码的复杂度
        int [] tmp = new int[arr.length];
        //指针指向前半段的第一个位置
        int point1 = start;
        //指针指向后半段的第一个位置
        int point2 = middle + 1;
        //制定开始插入的位置
        int loc = start;
        //两段数组,一段走完则结束循环
        while (point1 <= middle && point2 <= end) {
            //由于是按照升序排列,所以往临时数组中存放小的元素
            if(arr[point1] > arr[point2]){
                tmp[loc ++] = arr[point2 ++];
            }else {
                tmp[loc ++] = arr[point1 ++];
            }
        }

        //处理前半段数组元素没有处理完的情况
        while (point1 <= middle) {
            tmp[loc ++] = arr[point1 ++];
        }
        //处理后半段数组元素没有处理完的情况
        while (point2 <= end) {
            tmp[loc ++] = arr[point2 ++];
        }

        //将临时数组中的元素存放到原数组
        for (int i = start; i <= end; i++) {
            arr[i] = tmp[i];
        }
    }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值