对于《算法导论》第三版中的逆序数对问题(习题2.4),通过分治法和归并排序已降低时间复杂度的解法:
问题描述:
Let A[1..n] be an array of n distinct numbers. If i < j and A[i] > A[j] , then the pair (i,j) is called an inversion of A.
这里我们直接解决问题而不再赘述原题解答。
<span style="font-family:Comic Sans MS;font-size:18px;">
#include<iostream>
#include <sys/time.h>
#include <time.h>
#include <stdlib.h>
using namespace std;
long getCurrentTime()
{
struct timeval tv;
gettimeofday(&tv,NULL);
return tv.tv_sec * 1000 + tv.tv_usec / 1000;
}
int merge(int *a, int f, int m, int l)
{
int sum = 0;
int j = f;
int k = m + 1;
int n = l - f + 1;
int *b = new int[n];
if(!b)
{
cout<<"ERROR!";
return -1;
}
int i = 0;
for (i = 0; i < n; i++)
{
if (j>m || k>l)
break;
if (a[j] <= a[k])
{
b[i] = a[j];
j++;
}
else
{
b[i] = a[k];
sum = sum + (m - j + 1);
k++;
}
}
while (j <= m)
{
b[i++] = a[j++];
}
while (k <= l)
{
b[i++] = a[k++];
}
j = f;
for (i = 0; i < n; i++)
{
a[f+i] = b[i];
}
delete []b;
return sum;
}
/**递归调用归并排序**/
int mergeSort(int *a, int f, int len)
{
if (f < len)
{
int m = (f + len)/2;
return mergeSort(a, f, m) + mergeSort(a, m+1, len) + merge(a, f, m, len);
}
return 0;
}
int main()
{
int n;
cin>>n;
int *A = new int[n];
//产生大小为 n 的随机数列
srand((int)time(NULL));
for(int i =0; i < n; i++)
{
A[i] = rand()%100000;
}
long time = getCurrentTime();
cout<<mergeSort(A, 0, n-1)<<endl;
cout<<"time -> "<<getCurrentTime() - time<<" ms"<<endl;
}</span>
测试结果:
10000
24956458
time -> 16 ms
我们不妨与暴力方法进行一番比较:
<span style="font-family:Comic Sans MS;">
#include <iostream>
#include <sys/time.h>
#include <time.h>
#include <stdlib.h>
using namespace std;
long getCurrentTime()
{
struct timeval tv;
gettimeofday(&tv,NULL);
return tv.tv_sec * 1000 + tv.tv_usec / 1000;
}
int bubbleSort(int *A, int leng</span><span style="font-family:KaiTi_GB2312;">th)
</span><span style="font-family:Comic Sans MS;">{
int count = 0;
for(int i = 0; i < length; i++)
{
for(int j = i+1; j < length; j++)
{
if(A[j] < A[i])
{ count++; }
}
}
return count;
}
int main()
{
int n;
cin>>n;
int *A = new int[n];
srand((int)time(NULL));
for(int i =0; i < n; i++)</span><span style="font-family:KaiTi_GB2312;">
</span><span style="font-family:Comic Sans MS;"> {
A[i] = rand()%100000;
}
long time = getCurrentTime();
cout<<bubbleSort(A, n)<<endl;
cout<<"time -> "<<getCurrentTime() - time<<" ms"<<endl;
}</span>
测试结果:
10000
25137992
time -> 358 ms