运行时间具有对数性质的几种算法

运行时间具有对数性质的几种算法

对分查找算法

给定一个整数 X 和整数 A 0 A_{0} A0, A 1 A_{1} A1, A 2 A_{2} A2……, A N − 1 A_{N-1} AN1,后者已经预先排序并在内存中,求使得 A i A_{i} Ai=X 的下标 i ;如果 X 不在数据中,则返回-1.

int BinarySearch( const ElementType A[], ElementType x, int N)
{
	int low, mid, high;
	low = 0; high = N-1;
	while( low <= high )
	{
		mid=( low + high )/2;
		if( A[mid] < x)
			low = mid + 1;
		else
		{
			if( A[mid] > x)
				high = mid -1;
			else
				return mid;
		}
	}
	return -1;
}

显然,每次迭代再循环内的所有工作花费为O(1), 因此分析需要确定循环的次数。循环从 high - low = N-1 开始;到 high - low >= -1 结束。每次循环后 high - low的值减少一半,于是循环次数最多为[ log(N-1) ] + 2。
例如,若 high - low = 128, 则在各次迭代后 high - low 的最大值为64,32,16,8,4,2,1,0,-1。
因此,运行时间是O( logN )。

欧几里得算法

给定两个整数 M , N ,求 M , N 的最大公因数。

unsigned int Gcd( unsigned int M, unsigned int N )
{
	unsigned int Rem;
	while( N > 0 )
	{
		Rem = M % N;
		M = N;
		N = Rem;
	}
	return M;
}

因为余数不会超过原始值的一半,所以运行时间也是O( logN )。

冥运算

计算 x n x^n xn。(假设机器能够存储足够大的数)
注:如果n是偶数,则 x n x^n xn = x n 2 x^\frac{n}{2} x2n * x n 2 x^\frac{n}{2} x2n,如果n是奇数,那么 x n x^n xn = x n − 1 2 x^\frac{n-1}{2} x2n1 * x n − 1 2 x^\frac{n-1}{2} x2n1 * x。

long int Pow( long int x, unsigned int n)
{
	if( n == 0 )
		return 1;
	if( n == 1 )
		return x;
	if( IsEven ( n ) ) /* 判断是否是偶数 */
		return Pow( x * x, n / 2 ); /* 用x*x做参数,能提高效率 */
	else
		return Pow( x * x, n / 2) * x;
}

例如,为了计算 x 62 x^{62} x62,算法将如下进行,它只用到9次乘法:
x 3 x^3 x3 = ( x 2 x^2 x2 ) * x,
x 7 x^7 x7 = ( x 3 ) 2 { (x^3) }^2 (x3)2 * x,
x 15 x^{15} x15 = ( x 7 ) 2 { (x^7) }^2 (x7)2 * x
x 31 x^{31} x31 = ( x 15 ) 2 {( x^{15} )}^2 (x15)2 * x,
x 62 x^{62} x62 = ( x 32 ) 2 {( x^{32} )}^2 (x32)2
显然,所需要的乘法次数最多是2logn; 因为把问题分半最多需要两次乘法(如果n是奇数)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值