递归与分治(一)

递归的概念

递归是指由一种(或多种)简单的基本情况定义的一类对象或方法,并规定其他所有情况都能被还原为其他基本情况。递归使用到大量堆、栈空间,降低算法效率费时费内存。

递归一般可以解决以下三大类问题:
1、数据是按递归方式定义的,例如斐波拉切数列、阶乘、汉诺塔问题等
2、问题解决可以按递归方式实现,例如回溯
3、数据的结构形式是按递归定义的,例如树的遍历、图的搜索等。

用递归方法解决问题的过程中,递归函数的内部执行过程大致分为三步:
1、运行开始时为递归调用建立一个工作栈,其结构包括实参、局部变量和返回地址;
2、每次执行递归调用前,把递归函数的实参和局部变量的当前的值以及调用后的返回地址压栈;
3、每次递归调用结束后,将栈顶元素出栈,使相应的实参和局部变量恢复为调用前的值,然后转向返回地址指定的位置继续执行。

实例1:

下述代码给出用非递归和递归的方法输出n个自然数,从中体会递归和非递归思想的不同之处。

#include <iostream>

using namespace std;

void PRINT_A(int  n)   //非递归算法
{
	int i;
	for (i = 1; i < n; i++)
	{
		cout << i << " ";
	}
	cout << endl;
	return;
}

void PRINT_B(int n)  //递归算法
{
	if (n == 0)
		return;
	else
	{
		PRINT_B(n-1);
		cout << n <<" ";
	}
	return;
}

int main()
{
	int j;
	cin>>j;

	if (j == 1)
	{
		PRINT_A(10);
	}
	else if (j == 2)
	{
		PRINT_B(10);
		cout << endl;
	}
	return 0;
}

在这里插入图片描述
执行结果:

hong@debian:/mnt/hgfs/linux/cpp/recursion$ ./main
1
1 2 3 4 5 6 7 8 9
hong@debian:/mnt/hgfs/linux/cpp/recursion$ ./main
2
1 2 3 4 5 6 7 8 9 10

实例2:Fibonacci数列

无穷数列1,1,2,3,5,8,13,21,34,55,…被称为Fibonacci数列;它的递归公式:

n = 0 F(n) = 1
n = 1 F(n) = 1
n > 1 F(n) = F(n-1) + F(n-2)

n=0和n=1是递归函数的边界条件(递归出口),n>1为递归函数的递归方程。

#include <iostream>

using namespace std;

int fibonacci(int n);

int main()
{
	int n, result;
	cin >> n;
	result = fibonacci(n);
	cout << result << endl;
	return 0;
}


int fibonacci(int n)
{
	int goal;
	if (n == 1 || n ==2)
	{
		goal =1;
	}
	else
	{
		goal = fibonacci(n -1) + fibonacci(n - 2);
	}

	return goal;
}

根据递归方程可以画出一个下面的树状图,把问题分解成一个个子问题,子问题合并成一个复杂的问题。
在这里插入图片描述
执行结果:

hong@debian:/mnt/hgfs/linux/cpp/recursion$ ./main
8
21
hong@debian:/mnt/hgfs/linux/cpp/recursion$ ./main
10
55

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值