归并排序(java)

归并排序

归并排序,常用于计算数组中的逆序对数量

		@Test
        public void Test_873(){
            int[] arr = {2,3,4,1,-8,4,2,10};
            int n = arr.length;
            int[] help = new int[n];
            MergeSort(0, n-1,  help, arr);

            System.out.println(Arrays.toString(arr));
        }

        public void MergeSort(int l, int r, int[] help, int[] nums){
            if(l == r)
                return ;
            int mid = l + (r-l)/2;
            // 递归的分割左右两部分
            MergeSort(l, mid, help, nums);
            MergeSort(mid+1, r, help, nums);
            // 利用辅助数组进行排序
            for(int i=l;i<=r;i++){
                help[i] = nums[i];
            }
            // 合并分割的小区间,本质是合并两个有序数组,即[l,mid]和[mid+1, r]两个有序区间
            int left = l, right = mid+1;
            for(int i=l;i<=r;i++){
                if(left == mid+1){ // [l,mid]的数组已经遍历完了
                    nums[i] = help[right++];
                }else if(right == r+1){  // [mid+1, r]的数组已经遍历完了
                    nums[i] = help[left++];
                }else if(help[left] <= help[right]){
                    nums[i] = help[left++];
                }else if(help[left] > help[right]){
                    nums[i] = help[right++];
                }
            }
        }

当我们需要统计数组中的逆序对时,只需要在合并两个有序数组时,统计逆序对的数量即可
完整代码如下:

public int mergeSort(int l, int r, int[] help){
        if(l == r) return 0;

        int mid = l+(r-l)/2;
        int res = mergeSort(l, mid, help) + mergeSort(mid+1, r,help);

        // 利用辅助数组对[l,r]区间内进行排序
        for(int i=l;i<=r;i++){
            help[i] = nums[i];
        }
        // 排序的过程相当于是合并两个有序数组[l, mid] [mid, r]
        int left = l, right = mid+1; 
        for(int i=l;i<=r;i++){
            if(left == mid+1){
                nums[i] = help[right++];
            }else if(right == r+1){
                nums[i] = help[left++];
            }else if(help[left] <= help[right]){
                nums[i] = help[left++];
            }else if(help[left] > help[right]){
                res += mid - left+1;
                nums[i] = help[right++];
            }
        }
        return res;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值