十大排序之归并排序

// TODO 归并排序
public class MergeSort {
    public static void main(String[] args) {
//        int[] arr = {8, 4, 5, 7, 1, 3, 6, 2};
        // 测试时间复杂度 O(n log n)
        int [] arr = new int[80000];
        int[] temp = new int[arr.length];
        for (int i = 0; i < arr.length; i++) {
            // 生成 [0,8000000)的随机数
            arr[i] = (int) (Math.random()*8000000);
        }
        long start_Time = System.currentTimeMillis();
        mergeSort(arr,temp,0,arr.length-1);
        long stop_Time = System.currentTimeMillis();
        System.out.printf("耗费 %d ms",stop_Time - start_Time);
//        System.out.println(Arrays.toString(arr));

    }

    // 分 + 合 方法
    public static void mergeSort(int[]arr ,int[] temp,int left,int right){
        if(left<right){
            int center = (left + right) /2; // 中间索引
            // 向左递归 进行分解
            mergeSort(arr,temp,left,center);

            // 向右递归进行分解
            mergeSort(arr,temp,center +1,right);
            // 合并
            merge(arr,temp,left,center,right);
        }

    }

    /**
     * 合并方法
     *
     * @param arr    排序的原始数组
     * @param temp   合并存储中间结果的数组
     * @param left   最左边的索引
     * @param center 中间的索引
     * @param right  最右边的索引
     */
    private static void merge(int[] arr, int[] temp, int left, int center, int right) {
        int leftIndex = left; //  初始化 l ,左边的有序序列初始索引
        int c = center + 1; // 初始化 c,右边开始的索引
        int index = 0;  // temp 数组的初始索引

        /*
          第一步 先把 左右两步(有序)的数据按照规则填充到temp数组
          直到左右两边的有序序列,有一边处理完毕为止
         */
        while (leftIndex <= center && c <= right) {
            if (arr[leftIndex] <= arr[c]) {
                temp[index] = arr[leftIndex];
                leftIndex++;
            } else {
                temp[index] = arr[c];
                c++;
            }
            index++;
        }

        //(2) 把有剩余的一边数据依次全部填充到temp
        while (leftIndex <= center){
            temp[index] = arr[leftIndex];
            leftIndex ++;
            index ++;
        }
        while (c <= right){
            temp[index] = arr[c] ;
            index ++;
            c ++;
        }

        //(3) 把临时数组的拷贝到arr中
        // 注意 ,并不是 每次都拷贝所有
        index = 0;
        int tempLeft = left;
        while(tempLeft <= right){
            arr[tempLeft] = temp[index];
            index ++;
            tempLeft ++;
        }

    }
}

发布了39 篇原创文章 · 获赞 13 · 访问量 2290

猜你喜欢

转载自blog.csdn.net/qq_43205282/article/details/105399652