问题描述设n个不同的整数排好序后存于T[1:n]中。若存在下标i,1<=i<=n,使得T[i]=i,设计一个有效算法找到这个下标。要求算法在最坏情况下的计算时间为O(logn).
分析与解答:
由于n个整数是不同的,因此对任意1<=i<=n-1有T[i]<=T[i+1]-1
假设有n个数A1 A2 A3 ... A(i-1) Ai A(i+1) ... An
对应下标为 1 2 3 ... i-1 i i+1 ... n
如果Ai>i 则,由于下标是连续增长的,整数序列可能不是连续的,所以对于j>=i 有Aj-Ai >= j-i;
如果Ai<i则,同理,对于j<=i有,Ai-Aj >= i - j;
故有如下结论:
(1)对于1<i<=n-1,当T[i]>i时,对任意的i<=j<n,有T[j]-T[i] >= j-i,即T[j]>=T[i]+j-i>i+j-i=j
(2)对于1<i<=n,当T[i]<i时,对任意的1<=j<i,有T[i]-T[j] >= i-j,即T[j]<=T[i]-i+j<i-i+j=j
由(1)和(2)可知,用二分搜索算法可以在O(logn)时间内找到所要的下标。
非递归二分搜索:
int BinarySearch(int T[],int i,int n)
{
int low,high,mid;
low=0;high=n-1;
while(low<=high)
{
mid=(low+high)>>1;
if(i==T[mid])
{
printf("key %d is found,subscript is %d\n",i,mid)
return mid;
}
else if(i>T[mid])
low=mid+1;
else
high=mid+1;
}
}