归并排序:排序思想+代码

归并排序的步骤:

1.把要排序的数字串总中间分开,分别排左边和右边

2.对于左面的数字串,一样从中间分开,分成左和右......直到剩下1个数字时返回,把他和右边的数字归并。

注意:每次都是先对左面进行排序在排序右边,最后归并,而且为保证排序的稳定性,相等的值要把原来就在左边的排在左面 。

public class merge_sort {
    public static void main(String[] args) {
        int []arr = new int[]{8,6,9,4,3,9,2};
        process(arr,0,arr.length-1);
        for(int i = 0; i < arr.length; i++){
            System.out.print(arr[i] + " ");
        }
    }
    public static void process(int[]arr,int L,int R){
        if(L == R){
            return ;
        }
        int mid = L + ((R-L)>>1);
        process(arr,L,mid);//L到mid排序完毕
        process(arr,mid + 1,R);//mid+1到R排序完毕
        merge(arr,L,mid,R);//L到mid和mid+1到R归并
    }
    public static void merge(int[]arr,int L,int M,int R) {
        int[] help = new int[R - L + 1];//定义一个辅助空间
        int i = 0;//专门给help用的下标(index),指示当前help的数组到达的位置
        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++)
            // !!此处有坑:为什么是 L+i 呢?因为该函数排序的是arr(L,R),起始点是L
            arr[L + i] = help[i];
    }
}

时间复杂度:

        一共两个子程序:a = 2,每个子程序遍历总长度的1/2:b = 2,除了子程序merge的时间复杂度是O(n):d = 1

        T[n] = 2 * T[n/2] + O(n) 

满足情况②,所以:

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

master公式:也叫主定理。它提供了一种通过渐近符号表示递推关系式的方法。

                      应用Master定理可以很简便的求解递归方程。

        T [n] = a*T[n/b] + O (N^d)

        ①当d<log(b,a)时,时间复杂度为O(n^(logb a))

        ②当d=log(b,a)时,时间复杂度为O((n^d)*logn)

        ③当d>log(b,a)时,时间复杂度为O(n^d)

空间复杂度:O(n) ->需要一个辅助数组存放中间排序数组

该排序是稳定的

代码来自左神,b站搜索:算法大神左程云。

欢迎交流批评指正。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
归并排序是一种经典的排序算法,它采用分治的思想,将待排序的数组不断地分割成小的子数组,然后再将这些子数组合并成一个有序的数组。下面是归并排序的Java代码注释: ```java public class MergeSort { // 归并排序入口函数 public static void mergeSort(int[] arr) { int[] temp = new int[arr.length]; // 创建一个临时数组用于存储排序结果 mergeSort(arr, 0, arr.length - 1, temp); // 调用递归函数进行归并排序 } // 递归函数,实现归并排序 private static void mergeSort(int[] arr, int left, int right, int[] temp) { if (left < right) { int mid = (left + right) / 2; // 计算中间位置 mergeSort(arr, left, mid, temp); // 对左半部分进行归并排序 mergeSort(arr, mid + 1, right, temp); // 对右半部分进行归并排序 merge(arr, left, mid, right, temp); // 合并左右两部分 } } // 合并函数,将两个有序的子数组合并成一个有序的数组 private static void merge(int[] arr, int left, int mid, int right, int[] temp) { int i = left; // 左子数组的起始位置 int j = mid + 1; // 右子数组的起始位置 int k = 0; // 临时数组的起始位置 // 将左右两个子数组中较小的元素依次放入临时数组中 while (i <= mid && j <= right) { if (arr[i] <= arr[j]) { temp[k++] = arr[i++]; } else { temp[k++] = arr[j++]; } } // 将剩余的元素依次放入临时数组中 while (i <= mid) { temp[k++] = arr[i++]; } while (j <= right) { temp[k++] = arr[j++]; } // 将临时数组中的元素复制回原数组 for (int m = 0; m < k; m++) { arr[left + m] = temp[m]; } } } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值