排序:查找数组中逆序对的个数

    技术2026-06-21  4

    在一个数组A[1-n]中,如果i<j且A[i]>A[j];则(i,j)称为一个逆序对。

    如数组{2,3,8,6,1}中,有五个逆序对。分别为{1,5},{2,5},{3,5},{4,5},{3,4}

    具体参考<算法导论>二版 2-4 中的描述.可以根据合并排序中的算法来做统计.当左边小时,则计数加上右边已经插入 已排好序的个数.就是逆序对.

     

    #include<stdio.h> #include<stdlib.h> #include<math.h> int get_middle(int s,int e) { return (int)floor((s + e )/2); } int count=0; void merge_sort(int arr[],int start,int end) { int middle=get_middle(start,end); int l_length=middle - start +1,r_length=end - middle; int i=0,j=0, k=start; int *l_arr,*r_arr; int tmp; if(end <= start) { } else if(end - start==1) { if(arr[end]<arr[start]) { tmp=arr[start]; arr[start]=arr[end]; arr[end]=tmp; count++; } } else { merge_sort(arr,start,middle); merge_sort(arr,middle+1,end); l_arr = (int *)malloc((l_length) * sizeof(int)); r_arr= (int *)malloc((r_length) * sizeof(int)); for(i=0;i<l_length;i++) { l_arr[i]=arr[start+i]; } for(j=0;j < r_length;j++) { r_arr[j]=arr[middle+1+j]; } i=0; j=0; for(k=start;k<=end;k++) { if(i>=l_length) { arr[k]=r_arr[j++]; continue; } if(j>=r_length) { arr[k]=l_arr[i++]; count+=r_length; continue; } if( l_arr[i]<r_arr[j]) { count+=j; arr[k]=l_arr[i++]; } else { arr[k]=r_arr[j++]; } } } } void main() { int arr[5]={2,3,8,6,1}; int i=0,start=0,end=4; merge_sort(arr,start,end); for(i=0;i<5;i++) { printf("%d/n",arr[i]); } printf("/nTotal is %d inversion",count); getchar(); }  

     

     

    最新回复(0)