#include<iostream>
#include<cassert>
#include<ctime>
using namespace std;
//数组必须是有序的
//如果找到target,返回相应的索引index
//如果找不到,返回-1
template<typename T>
int binarySearch(T arr[], int n, T target)
{
//在[l,r]中寻找target
int l ,r;
l = 0; r = n-1;
while(l <= r)
{
//这里有一个bug 就是当l和r是一个很大的整数的时候,它们加在一起就有可能出现溢出的情况
//int mid = (l+r)/2; //我爱写成 (l-r+1)/2
//避免的方法,不用加法,用减法来实现
int mid = l + (r-l)/2;
if( arr[mid] == target )
return mid;
if(target < arr[mid])
r = mid - 1; //这里要小心
else
l = mid + 1;
}
return -1;
}
//递归的实现通常比较容易,因为每次只需要考虑一个子问题
int __BinarySearch2(int arr[], int l, int r, int target)
{
if(l > r)
return -1;
int mid = l + (r-l)/2;
if(arr[mid] == target)
return mid;
else if(arr[mid] > target)
return __BinarySearch2(arr,l,mid-1,target); //掉了两个return
else if(arr[mid] < target)
return __BinarySearch2(arr,mid+1,r,target);
return -1;
}
//用一个包裹函数,保证借口统一
template<typename T>
int binarySearch2(T arr[],int n, T target)
{
return __BinarySearch2(arr,0,n-1,target);
}
//比较递归和非递归写法的二分查找效率
int main(int argc, char const *argv[])
{
int n = 1000000;
int* arr = new int[n];
for(int i = 0 ;i < n; i++)
{
arr[i] = i;
}
//测试非递归
clock_t startTime = clock();
for(int i = 0; i< 2*n; i++)
{
int v = binarySearch(arr,n,i);
if(i < n)
assert( v == i);
else
assert( v == -1);
}
clock_t endTime = clock();
cout << "binarySearch(without Recursion): " << double(endTime-startTime) / CLOCKS_PER_SEC << "s" << endl;
//测试递归的二分查找s
startTime = clock();
for(int i = 0; i< 2*n; i++)
{
int v = binarySearch2(arr,n,i);
if(i < n)
assert( v == i);
else
assert( v == -1);
}
endTime = clock();
cout << "binarySearch(Recursion): " << double(endTime-startTime) / CLOCKS_PER_SEC << "s" << endl;
delete [] arr;
return 0;
}
c++递归和非递归实现二分查找法并比较其性能
最新推荐文章于 2021-12-09 22:26:53 发布