c++递归和非递归实现二分查找法并比较其性能

#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;
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

五月的天气

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值