基本排序算法--归并排序随笔

基本思想

归并排序(MERGE-SORT)是利用归并的思想实现的排序方法,该算法采用经典的分治(divide-and-conquer)策略(分治法将问题分(divide)成一些小的问题然后递归求解,而治(conquer)的阶段则将分的阶段得到的各答案"修补"在一起,即分而治之)。
总的来说,是先将数组拆分,再合并;每次拆分,在原来的基础上,将数组拆分为两份,若可继续拆分;则继续拆分,直到无法拆分;再将拆分的数组排序并合并
例如:【1,5,4,3,7,6,8,2,9, 10】----> 【1,5,4,3,7】【6,8,2,9,10】
—>【1,5,4】【3,7】【6,8,2】【9,10】—>【1,5】【4】【3,7】【6,8】【2】【9,10】
—>【1,4,5】【3,7】【2,6,8】【9,10】—>【1,3,4,5,7】【2,6,8,9,10】
—>【1,2,3,4,5,6,7,8,9,10】

流程图

在这里插入图片描述

JAVA编码实现
/**
 * 归并排序
 */
public class MergeSort extends Sort {

    public static void main(String[] args) {
//        DataCheck.checkArithmetic(new MergeSort());
        MergeSort is = new MergeSort();
        int[] arr = is.sort(new int[]{1, 52, 6, 23, 5, 4, 3, 7, 15 ,17});
        is.print(arr);
        System.out.println();
    }

    @Override
    public int[] sort(int[] arr) {
        return  sortOne(arr, 0, arr.length - 1);
//        return sortBase(arr);
    }

    /**
     * 归并排序
     * @param arr  需排序的数组
     * @param left  排序左下标【开始坐标】
     * @param right 排序右下标【结束坐标】
     * @return
     */
    public int[] sortOne(int[] arr, int left, int right){
        if(left == right){
            return arr;
        }
        //获取
        int mid = left + (right - left) / 2;
        // 排序左边数组
        sortOne(arr, left, mid);
        //排序右边数组
        sortOne(arr, mid + 1, right);
        //将排序好的左边数组 与 右边数组合并排序
        return merge(arr, left, mid + 1, right);
    }

    /**
     * 将一个连续的 左右两个有序数组的连接体排序,例:【1, 3, 6, 11, 5, 7, 9, 18]
     * @param arr  数组
     * @param leftPtr  左数组开始索引 [0]
     * @param rightPtr  右数组开始索引[4]
     * @param rightBound  右数组结束索引【包含】[7]
     */
    public int[] merge(int[] arr, int leftPtr, int rightPtr, int rightBound){
        //左数组结束索引
        int mid = rightPtr -1;
        int[] temp = new int[rightBound - leftPtr + 1];

        int i = leftPtr; int j = rightPtr, k = 0;
        while(i <= mid && j <= rightBound){
            temp[k++] = arr[i] <= arr[j] ? arr[i++] : arr[j++];
        }

        while(i <= mid){
            temp[k++] = arr[i++];
        }
        while(j <= rightBound){
            temp[k++] = arr[j++];
        }
        for(int m = 0; m < temp.length; m++){
            arr[leftPtr + m] = temp[m];
        }
        return arr;
    }

    //
    public int[] sortBase(int[] arr){
       if(arr.length == 2){
           if(arr[0] > arr[1]){
               swap(arr, 0, 1);
           }
           return arr;
       }else if(arr.length <= 1){
           return  arr;
       }

       int num = arr.length / 2;
       int[] left = new int[num];
       int[] right = new int[arr.length-num];
       System.arraycopy(arr, 0, left, 0, num);
       System.arraycopy(arr, num, right, 0, arr.length-num);
       return mergeOrderly(sortBase(left), sortBase((right)));
    }


    /**
     * 将两个有序的数组 进行有序的合并
     * @param arrLeft
     * @param arrRight
     * @return
     */
    public int[] mergeOrderly(int[] arrLeft, int[] arrRight){
        int[] arr = new int[arrLeft.length + arrRight.length];
        int left = 0, right = 0;
        for(int i = 0; i < arr.length; i++){
            if(left >= arrLeft.length || right >= arrRight.length){
                arr[i] = left >= arrLeft.length ? arrRight[right++] : arrLeft[left++];
                continue;
            }
            arr[i] = arrLeft[left] <= arrRight[right] ? arrLeft[left++] : arrRight[right++];
        }
        return arr;
    }

    //替换
    public void swap(int[] arr, int i, int j){
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }

    //打印int数组
    public void print(int[] arr){
        for(int i = 0; i < arr.length; i++){
            System.out.print(arr[i] + " ");
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值