《算法导论》中的逆序数对问题

对于《算法导论》第三版中的逆序数对问题(习题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


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值