有一个数的序列A[1]、A[2] 、A[3] 、…… 、A[n],若i<j,并且A[i]>A[j],则称A[i]与A[j]构成了一个逆序对,设计算法求数列A中逆序对的个数.
1 package org.xiu68.exp.exp1; 2 3 public class Exp1_3 { 4 public static void main(String[] args) { 5 int[] arr=new int[]{2,1,1,1,1,1,2}; 6 System.out.println(countInverseNum(arr, 0, arr.length-1)); 7 } 8 9 public static int countInverseNum(int[] arr,int start ,int last){ 10 if(start<last){ 11 int mid=(start+last)/2; 12 int firstPart=countInverseNum(arr, start, mid); //计算前一部分的逆序数 13 int lastPart=countInverseNum(arr,mid+1,last); //计算后一部分的逆序数 14 int midPart=sortAndCountNum(arr, start, mid, last); //计算两部分之间的逆序数 15 return firstPart+lastPart+midPart; //三者相加即为总的逆序数 16 } 17 return 0; 18 } 19 20 //二并一进行归并排序,并且计算两部分之间的逆序数 21 public static int sortAndCountNum(int[] arr,int start,int mid,int last){ 22 int i=start; 23 int j=mid+1; 24 int k=0; 25 int num=0; 26 int[] temArr=new int[last-start+1]; //辅助空间 27 28 29 while(i<=mid && j<=last){ 30 if(arr[i]<=arr[j]) 31 temArr[k++]=arr[i++]; 32 33 else{ //arr[i]>arr[j],即arr[i]大于arr[j]后面的所有元素 34 temArr[k++]=arr[j++]; 35 num+=mid-i+1; 36 } 37 } 38 39 40 while(i<=mid) 41 temArr[k++]=arr[i++]; 42 43 while(j<=last) 44 temArr[k++]=arr[j++]; 45 46 for(int p=0;p<temArr.length;p++) 47 arr[start++]=temArr[p]; 48 49 return num; 50 } 51 }