归并排序与分治法求逆序对数

分治模式的步骤:分解、解决、合并。

MergeSort的思想也是如此,把数组从中间分成两部分,然后分别排好序,再用merge将两个已经排好序的

数组归并成一个数组。子数组的排序,可以再用MergeSort,即递归。所以,归并排序的核心是归并。

// Mergesort.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include 
   
   
    
    
#include 
    
    
     
     
#include 
     
     
      
      
#include 
      
      
       
       
#include 
       
       
         using namespace std; const int MAX=30;//MAX是哨兵牌无穷大,因为测试时的数都小于30,可用climits库中的INT_MAX等等 //nums是要排序的数组,p,q,r是下标,满足p<=q 
        
          & nums, int p, int q,int r)//p是左端,q是右端 { if(p<=q&& q<=r&&r<=nums.size()) { int n1=q-p+1,n2=r-q; vector 
         
           L(n1+1),R(n2+1);//临时数组多一个空间,为了放哨兵牌 int i,j; for(i=0;i 
          
            R[j]) { nums[k]=R[j++]; }else { nums[k]=L[i++]; } } } } //分治法,左右都排好序了,再归并 void MergeSort(vector 
           
             & nums, int p, int r) { int q,inversion=0; if(p 
             
             
            
           
          
         
       
      
      
     
     
    
    
   
   
下面介绍逆序对的概念:假设A[1...n]是一个有n个不同数的数组。若i<j且A[i]>A[j],则称对偶(i,j)为A 的一个逆序对。

分治解决:把A[1...n]根据下标分成两部分,A[1...q]和A[q+1,...,n]。它的逆序对数分为3部分,A[1...q]的逆序对数

和A[q+1,...,n]的逆序对数,以及它俩之间组成的逆序对。前面两个是同一问题的子问题,递归求,即可。只需考虑

它俩之间的逆序对,可以考虑再归并时计数,A[1...q]在left数组中,A[q+1,...,n]在right数组中,当left中的数大于right

内的数时就有逆序对了,计数见代码。

// cha12_2Count_Inversions.cpp : 定义控制台应用程序的入口点。
//

// cha2_1.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include 
    
    
     
     
#include 
     
     
      
      
#include 
      
      
       
       
#include 
       
       
        
        
#include 
        
        
          using namespace std; const int MAX=30; int MergeInversion(vector 
         
           & nums, int p, int q,int r) { int inversions=0; if(p<=q&& q<=r&&r<=nums.size()) { int n1=q-p+1,n2=r-q; vector 
          
            L(n1+1),R(n2+1); int i,j; for(i=0;i 
           
             R[j]) { inversions+=n1-i;//为什么是n1-i呢?若有L[i]>R[j],因为L是排好序的,所以L[i]后面的数也一定大于R[j] //即它们都可以与R[j]组成逆序对,一共有n1-i个。 nums[k]=R[j++]; }else { nums[k]=L[i++]; } } } return inversions; } int MergeSort(vector 
            
              & nums, int p, int r) { int q,inversion=0; if(p 
              
              
             
            
           
          
        
       
       
      
      
     
     
    
    

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值