🚀个人主页:欢迎访问Ali.s的首页
⏰ 最近更新:2022年8月14日
⛽ Java框架学习系列:【Spring】【SpringMVC】【Mybatis】
🔥 Java项目实战系列:【飞机大战】【图书管理系统】
🍭 Java算法21天系列:【查找】【排序】【递归】
⛳ Java基础学习系列:【继承】【封装】【多态】
🏆 通信仿真学习系列:【硬件】【通信】【MATLAB】
🍄 个人简介:通信工程本硕🌈、Java程序员🚴。目前只会CURD😂
💌 点赞 👍 收藏 💗留言 💬 都是我最大的动力💯
活动地址:CSDN21天学习挑战赛
一、递归算法
递归算法(recursion algorithm)是指一种通过重复将问题分解为同类的子问题而解决问题的方法。递归式方法可以被用于解决很多的编程问题,因此其思想是十分重要的。绝大多数编程语言支持函数的自调用,在这些语言中函数可以通过调用自身来进行递归。计算理论可以证明递归的作用可以完全取代循环,因此在很多函数编程语言中习惯用递归来实现循环。
我想每个人都不陌生。举个从小就听过的例子:从前有座山,山里有座庙,庙里有个和尚,和尚在讲故事,从前有座山,山里有座庙,庙里有个和尚,和尚在讲故事,从前有座山…这便是递归的好例子,很好的阐述了递归的思想。
二、实现逻辑
(1)递归是自己调用自己。
(2)递归通常不在意具体操作,只关心初始条件、结束条件和上下层关系。
(3)递归函数需要有结束条件,即递归不能无限制的执行下去。
(4)递归可以被栈替代。有些递归可以优化。
三、举个例子
在编程中,递归算法的运用十分常见,在很多复杂的问题的求解时,往往是使用递归的思想,这里需要提醒的是它与循环还是有区别的,循环是重复的去做一件事,但做这件事的往往是同一个对象,而递归是不同的对象去重复做同一件事,所以循环与递归的复杂度和作用对象不同。常见的递归的问题有很多,下面举两个例子:
1、汉诺塔问题
汉诺塔是我们小时候经常玩的一种游戏,游戏规定有n个大小不等的盘子放在一个塔A上面,自底向上按照从小到大的顺序排列。要求将所有n个盘子搬到另一个塔C上面,可以借助一个塔B中转,但是要满足任何时刻大盘子不能放在小盘子上面。
基本思想分三步,先把上面的N-1个盘子经C移到B,然后将最底下的盘子移到C,再将B上面的N-1个盘子经A移动到C。那么代码实现如下:
void hano(char a, char b, char c, int n) {
if (n > 0) {
hano(a, c, b, n-1);
move(a, c);
hano(b, a, c, n-1);
}
}
void move(char a, char b)
{
cout << a << "->" << b << endl;
}
2、全排列问题
全排列问题在高中数学概率部分经常会遇到,也是一个十分常见运用递归思想的例子,设从n个不同元素中任取m(m≤n)个元素,按照一定的顺序排列起来,叫做从n个不同元素中取出m个元素的一个排列。当m=n时所有的排列情况叫全排列。
inline void Swap(int &a,int &b)
{
int temp=a;
a=b;
b=temp;
}
void Perm(int list[],int k,int m)
{
if (k == m-1)
{
for(int i=0;i<m;i++)
{
printf("%d",list[i]);
}
printf("n");
}
else
{
for(int i=k;i<m;i++)
{
Swap(list[k],list[i]);
Perm(list,k+1,m);
Swap(list[k],list[i]);
}
}
}
四、算法评价
递归虽然有简洁的优点,但它同时也有显著的缺点。 递归由于是调用自身,而函数调用是有时间和空间的消耗,每一次函数调用,都需要在内存栈中分配空间以保存参数, 返回地址及临时变量,而且往栈里压入数据和弹出数据都需要时间,这就不难理解递归实现的效率不如循环。递归中有可能很多计算是重复的, 从而对性能带来很大的负面影响,所以在使用递归算法时,应该注意算法的深度,避免造成超时或者空间爆炸的情况。
总结
通过对递归算法进行了介绍,举出实例进行模拟递归的过程,递归的思想很重要,能够很好的简化负载的问题,虽然有它不足的地方,但是可以进行修改,比如对递归的出口做剪枝操作等,避免时间溢出和内存爆炸。