十大经典排序算法之归并排序(Java代码实现)

算法原理

归并排序(Merge Sort)是建立再归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列间有序。将两个有序表合并成一个有序表,称为2-路归并。

算法描述

  1. 申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列。
  2. 设定两个指针,最初位置分别为两个已排序序列的起始位置。
  3. 比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置。
  4. 重复步骤3直到某一指针到达序列尾。
  5. 将另一序列剩下的所有元素直接复制到合并序列尾。

动图展示

注:动图来源于菜鸟教程
在这里插入图片描述

算法实现



/**
 * 归并排序
 */
public class MergeSort {

    public static void main(String[] args) {

        int[] arr = {3,44,38,5,47,15,36,26,27,2,46,4,19,50,48};

        arr = mergeSort(arr);

        printArray(arr);

    }

    public static void printArray(int[] arr){
        for(int a : arr)
            System.out.print(a+",");
        System.out.println();
    }

    public static int[] mergeSort(int[] arr){
        if(arr.length < 2){
            return arr;
        }

        int middle = (int) Math.floor(arr.length/2);
        int[] left = Arrays.copyOfRange(arr,0,middle);
        int[] right = Arrays.copyOfRange(arr,middle,arr.length);

        return mergeSort(mergeSort(left),mergeSort(right),arr.length);
    }

    public static int[] mergeSort(int[] left, int[] right, int length){

        int[] result = new int[length];

        int i =0;

        while(left.length > 0 && right.length > 0){ // 左右两组都有数据时
            if(left[0] <= right[0]){
                result[i] = left[0]; // 目标数组添加第一项
                int[] temp = new int[left.length-1];
                System.arraycopy(left,1,temp,0,temp.length); // 移除数组第一项
                left = temp;
            }else {
                result[i] = right[0]; // 目标数组添加第一项
                int[] temp = new int[right.length-1];
                System.arraycopy(right, 1, temp, 0, temp.length); // 移除数组第一项
                right = temp;
            }
            i++;
        }

        while (left.length > 0){ // 右边数组无数据时
            result[i] = left[0]; // 目标数组添加第一项
            int[] temp = new int[left.length-1];
            System.arraycopy(left,1,temp,0,temp.length); // 移除数组第一项
            left = temp;
            i++;
        }

        while (right.length > 0){ // 左边数组无数据时
            result[i] = right[0]; // 目标数组添加第一项
            int[] temp = new int[right.length-1];
            System.arraycopy(right, 1, temp, 0, temp.length); // 移除数组第一项
            right = temp;
            i++;
         }

        return result;

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值