归并排序

2018-06-06  本文已影响0人  stoneyang94

思路

首先让数组中的每一个数,视为长度为1的有序区间,
然后把相邻的长度为1的有序区间进行合并,得到最大长度为2的有序区间,
接下来把相邻的长度为2的有序区间进行合并,得到最大长度为4的有序区间,
然后是对相邻的长度为4的有序区间进行合并,依次进行,
直到数组中的所有的数合并成一个统一的区间,排序结束。

归并排序的重点是对两个有序数组进行合并的过程,然后在这个基础上进行递归和分治。

指标

时间复杂度 O(n*logn)
空间复杂度O(n)

代码

public class MergeSort {

    public static void mergeSort(int[] arr) {
        if (arr == null || arr.length < 2) {
            return;
        }
        mergeSort(arr, 0, arr.length - 1);
    }
    //一个中点---------------------
    public static void mergeSort(int[] arr, int l, int r) {
        if (l == r) {//只有一个数了
            return;
        }
        int mid = l + ((r - l) >> 1);//防止溢出;位运算快于除法
        mergeSort(arr, l, mid);//左半边,T(N/2)
        mergeSort(arr, mid + 1, r);//右半边,T(N/2)
        merge(arr, l, mid, r);
    }
    //两个指针-------------------------
    public static void merge(int[] arr, int l, int m, int r) {
        int[] help = new int[r - l + 1];//辅助数组
        int i = 0;
        int p1 = l;
        int p2 = m + 1;
        while (p1 <= m && p2 <= r) {
            help[i++] = arr[p1] < arr[p2] ? arr[p1++] : arr[p2++];
        }
        //两个while只会发生一个。两个只会有一个越界
        //负责把剩下的数组拷贝进辅助数组
        while (p1 <= m) {
            help[i++] = arr[p1++];
        }
        while (p2 <= r) {
            help[i++] = arr[p2++];
        }
        for (i = 0; i < help.length; i++) {
            arr[l + i] = help[i];
        }
    }

    private static void swap(int[] arr, int i, int j) {
        int tmp = arr[i];
        arr[i] = arr[j];
        arr[j] = tmp;
    }

    private static void printArray(int[] arr) {
        if (arr == null) {
            return;
        }
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + " ");
        }
        System.out.println();
    }

    public static void main(String[] args) {
        int[] arr = new int[] { 3, 5, 4, 2, 6, 7, 1, 9, 8 };
        mergeSort(arr);
        printArray(arr);
    }
}
两个指针p1,p2

输出

排序后
上一篇 下一篇

猜你喜欢

热点阅读