排序算法之:归并排序

归并排序的思想:归并的思想是分治法的思想,首先对已知数组自上而下递归地分割程序两份,直达最后不能再分为止,然后对已有的子数组(两个部分)比较大小后自下而上合并为一个数组,然后将合并的数组拷贝到原来的数组即可;

空间复杂度为:O(n),是因为合并的过程中需要一个辅助的数组;

时间复杂度为:O(nlogn),是一种稳定的排序算法;

package suanfa.mysort;

/**
 * @description:
 * @author: fangchangtan
 * @create: 2019-04-22 10:01
 */
public class MergeSort {

    public static void main(String[] args) {
        int[] test = {5,2,4,3,5,13,8,11,12};
        mergeSort(test,0,test.length-1);
        for (int i = 0; i < test.length; i++) {
            System.out.print(test[i]+",");
        }

    }

    /**分治法:1.分
     * 递归排序的入口:三个参数
     * @param arr
     * @param left
     * @param right
     */
    public static void mergeSort(int[] arr, int left, int right) {
        if (left < right) {
            int mid = (left + right) / 2;
            mergeSort(arr, left, mid);
            mergeSort(arr, mid + 1, right);
            merge(arr,left,mid,right);
        }

    }

    /**
     * 分治法:2.治
     * @param arr
     * @param left
     * @param mid
     * @param right
     */
    public static void merge(int arr[], int left, int mid, int right) {
        int[] tem = new int[right - left+1];//申请一个第n轮归并需要使用的临时数组;//也可以使用
        int i = left;//归并的第一部分开始的下标
        int j = mid+1;//归并的第二部分的开始下标
        int k = 0;//给临时数组使用

        while (i <= mid && j <= right) {
            if (arr[i] < arr[j]) {
                tem[k++] = arr[i++];
            } else {
                tem[k++] = arr[j++];
            }
        }
        while (i <= mid) {
            tem[k++] = arr[i++];
        }
        while (j <= right) {
            tem[k++] = arr[j++];
        }
        for (int k2 = 0;k2<tem.length;k2++) {
            arr[k2 + left] = tem[k2];
        }

    }

}