C++算法之递归折半查找(七)

只有排序之后的数据才能进行折半(二分)查找。
引用博客的一段话来理解递归如何理解递归


要理解递归,我们要退一步,了解另一个概念——「分而治之」。稍微了解程序设计的人,对这个概念应该不陌生。通俗的说,假如我们有这样一个问题A,如果能把A分解成一系列比A更容易解决的子问题(A0,A1,A2……An),通过解决子问题(A0,A1,A2……An)来最终达成解决问题A,这个就是「分而治之」。从本质上来说递归就是「分而治之」概念的一个应用。以递归计算斐波纳切数列来举例,要计算斐波纳切数列的第n项该怎么办?通过数列的定义我们知道第n项的值等于第 n-1 项加上第 n-2 项,所以我们可以把计算第n项这个问题分解成计算 n-1 项和 n-2 项两个子问题。我们知道计算 n-1 和 n-2 项要比计算n项更容易点(因为 n-1 和 n-2 都比n要来得小)。那么 n-1 项由如何计算呢?根据定义 n-1 项等于 (n-1)-1 项和 (n-1)-2 项的值,好了,我们在这里碰到了递归,好,我们先就此打住。因为n在一直减少,最终会减到1,再减到0,而第0项和第1项的值我们不用计算就知道的,这就是递归终结的时候了。

通用概括一下,在面对递归问题时,我们可以用「分而治之」的概念去帮助理解。步骤如下:

  1. 把问题分解成更容易解决的子问题集合,比如可以把计算斐波那契数列的第n项问题分解转换成计算第n-1项加上第n-2项这两个子问题
  2. 假设我们有一个函数可以应用在所有的子问题上,比如计算斐波那契数列的fibo函数
  3. 基于步骤2的函数,实现如何把子问题的解拼成最终问题的解,这就是递归部分,在计算斐波那契数列的例子里就是fibo(n-1) + fibo(n-2)部分
  4. 递归部分确定了,然后再考虑子问题最终简化到到最底层时该返回什么值。
  5. 上面4步都做好了之后,剩下的就只是毫无条件的相信计算机了……

C++代码如下

#include <iostream>

using namespace std;

int BinarySearch_I(int *a, const int x, const int n);
int BinarySearch_R(int *a, const int x, const int left, const int right);

int main()
{
	int m[] = {1,2,3,4,5,6,7,8,9};
	int 结果;
	int num = 7;
	if((结果 = BinarySearch_R(m,num,0,8))<0)
	{
		cout << "递归算法: 没找到!" << endl;
	}else{
		cout << "递归算法: 在m[" << 结果 << "]找到" << num << endl;
	}


	if((结果 = BinarySearch_I(m,num,9))<0)
	{
		cout << "迭代算法: 没找到!" << endl;
	}else{
		cout << "迭代算法: 在m[" << 结果 << "]找到" << num << endl;
	}

	return 0;
}

//迭代
int BinarySearch_I(int *a, const int x, const int n)
{
	int left = 0, right = n-1;
	while(left <= right)
	{
		int middle = (left+right)/2;
		if(x<a[middle]) right = middle-1;
		else if(x>a[middle]) left = middle + 1;
		else return middle;
	}
	return -1;
}

//递归
int BinarySearch_R(int *a, const int x, const int left, const int right)
{
	if(left<=right)
	{
		int middle = (left+right)/2;
		if(x<a[middle]) return BinarySearch_R(a,x,left,middle-1);
		else if(x>a[middle]) return BinarySearch_R(a,x,middle+1,right);
		else return middle;
	}
	return -1;
}
  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值