分治算法---求解逆序数问题

[实验目的]

基本掌握分治算法的原理.

掌握二路归并排序的算法及递归程序的设计.

【问题描述】 给定一个整数数组A=(a0,a1,,an-1若 iai>aj,则<ai, aj>就是一个逆序对。例如数组(3,1,4,5,2)中,含有4个逆序对。编写一个程序,采用分治法中的二路归并排序算法,递归地求解A中的逆序对的个数,即逆序数。

【提示】采用分治法中的二路归并排序算法,对数组进行排序,在归并各个子序列时,统计逆序对的个数,如下图所示:分治算法---求解逆序数问题_第1张图片

参考代码为:

/*****求字符串a的逆序数ans***************/

int ans;   //全局变量,累计逆序数

void Merge(int a[],int low,int mid,int high) //两个相邻有序段归并

{  int i=low;

   int j=mid+1;

   int k=0;

   int *tmp=(char *)malloc((high-low+1)*sizeof(int));

   while(i<=mid && j<=high) //二路归并

   {  if(a[i]>a[j])

      {  tmp[k++]=a[j++];

         ans+=mid-i+1;

      }

      else tmp[k++]=a[i++];

   }

   while(i<=mid) tmp[k++]=a[i++];

   while(j<=high) tmp[k++]=a[j++];

   for(int k1=0;k1 //tmp[0..k-1]=>a[low..high]

       a[low+k1]=tmp[k1];

   free(tmp);

}

【算法时间复杂度分析】

设整个算法的执行时间为T(n),显然Merge(a,0,n/2,n-1)的执行时间为O(n),所以得到以下递推式:

         T(n)=1 n=1

T(n)=2T(n/2)+O(n) n>1

【思考】如果有多组长度相同的整数数列,每一组都求解逆序对数,然后,按“最多逆序数”到“最少逆序数”的顺序输出所有数列。若两个数列的逆序对个数相同,按原始顺序输出它们,该如何修改程序,完成此问题?

符合题意的算法如下:

分治算法---求解逆序数问题_第2张图片

#include
#define MAXN 55
#define MAXM 105
using namespace std;
int ans;
void Merge(char a[],int low,int mid,int high){
    int i=low;
    int j=mid+1;
    int k=0;
    char *tmp=(char *)malloc((high-low+1)*sizeof(int));
    while(i<=mid && j<=high){
        if(a[i]>a[j]){
            tmp[k++]=a[j++];
            ans+=mid-i+1;
        }
        else tmp[k++]=a[i++];
    }
    while(i<=mid) tmp[k++]=a[i++];
    while(j<=high) tmp[k++]=a[j++];
    for(int k1=0;k1>n;
    cout<<"please input the content:"<>a;
    number=inversion(a,n);
    cout<<"逆序数的对数是:"<

你可能感兴趣的:(算法和数据结构,算法,线性代数)