分治算法值递归概述

分治算法之递归概述

递归定义

在调用一个函数的过程中又出现了直接或间接调用该函数本身

直接调用

p函数定义中调用p函数

间接调用

p函数定义中调用q函数

递归的要素

  1. 递归表达式(递归方程)
  2. 递归结束条件(边界条件)

示例:

sum ⁡ ( n ) = { 1 n = 1 sum ⁡ ( n − 1 ) + n n > 1 \operatorname{sum}(\mathrm{n})=\left\{\begin{array}{cl} 1 & \mathrm{n}=1 \\ \operatorname{sum}(\mathrm{n}-1)+\mathrm{n} & \mathrm{n}>1 \end{array}\right. sum(n)={1sum(n1)+nn=1n>1
n=1为边界条件,n>1时为递归方程

能用递归解决的问题需要满足的条件

  1. 需要解决的问题可以转化为一个或者多个子问题来求解,而这些子问题的求解方法与原问题完全相同,只是数量规模不同
  2. 递归调用的次数必须是有限的
  3. 必须有结束递归的条件来终止递归

递归的应用场景

  1. 定义是递归的(阶乘,斐波那契数列等)
  2. 数据结构是递归的(单链表,二叉树等)
  3. 问题求解方式是递归的(汉诺塔,回溯法等)

递归的优缺点

优点:
结构清晰,可读性强,容易用数学归纳法来证明算法的正确性
缺点:
运行效率较低,费时费空间
解决方法:可以将某些递归转化为非递归算法(PS:估摸着就是把尾递归转化为循环,个人想法,未必正确)

实例—汉诺塔问题

问题描述:
A,B,C三根柱子,n个圆盘,自下而上,由大到小
将这n个圆盘从A柱移动到C柱,并且在C柱也需要按照从下往上由大到小的顺序叠放
问题规则:

  1. 每次只能移动一个圆盘
  2. 任何时刻都不允许吧大的圆盘放在小的上面
  3. 在满足上述两个规则下,可以将圆盘移到A,B,C中任意一根柱子上

设计思路:
(1)将n-1个圆盘从A->B
(2)将一个圆盘从A->C
(3)将n-1个圆盘从B->C


//伪代码
input n
begin
	if n>0
		Hanoi(n-1,A,C,B)
		Move(A,C)
		Hanoi(n-1,B,A,C)
end

时间复杂度分析
T(1)=O(1)
T(n)=2T(n-1)+O(1)=( 2 n 2^{n} 2n-1)*O(1)=O( 2 n 2^{n} 2n)


//C/C++实现
#include<stdio.h>
int step;
void move(int n,char a,char b){
	printf("%d: move %d from %c to %c.\n",++step,n,a,b);
}
void hanoi(int n,char a,char b){
	if(n>0){
		hanoi(n-1,a,c,b);
		move(n,a,c);
		hanoi(n-1,b,a,c);	
	}
}
int main(){
	int n;
	scanf("%d", &n);
	hanoi(n,'A','B','C');
}

递归算法设计问题合集

问题1:递归算法执行中的递归状态表示

在函数的参数引用中,我们有两种引用方式:(1)int f(int n) (2)int f(int &n) 对于此上两种方式进行讲解
(1)int f(int n) 此种方式是将n放入到系统栈中,在函数结束时自动返回,咋递归函数中每次的这种变量实质上是不同的变量,彼此之间并无关系
(2)int f(int &n) 此种方式是将n放入一个指定的内存空间中,在递归函数中每次对此的引用实质上是对同一个变量的引用·

问题2:递归算法执行中临时参数的初始化

递归调用分为两部分:结束条件和递归方程,于是临时变量的初始化就会有两种情况(1)对于满足结束条件是的临时变量(2)对于不满足结束条件,仍然处于递归方程中的临时变量,这两种情况必须搞清楚(PS:这个我觉得只要涉及临时变量有使用递归的人一般都要设置的吧。。。)

递归函数转化为非递归函数

将递归函数转化为非递归函数我们可以通过栈
我们在设计栈时除了要保存递归函数的参数以外,我们还需要设计一个标志成员,用来展示这个小问题是否被得到解决
注:用结构体来完成需要被保存的属性

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值