• 【21天学习挑战】经典算法之【递归算法】


    🚀个人主页:欢迎访问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;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    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]); 
    		}
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    四、算法评价

    递归虽然有简洁的优点,但它同时也有显著的缺点。 递归由于是调用自身,而函数调用是有时间和空间的消耗,每一次函数调用,都需要在内存栈中分配空间以保存参数, 返回地址及临时变量,而且往栈里压入数据和弹出数据都需要时间,这就不难理解递归实现的效率不如循环。递归中有可能很多计算是重复的, 从而对性能带来很大的负面影响,所以在使用递归算法时,应该注意算法的深度,避免造成超时或者空间爆炸的情况。


    在这里插入图片描述

    总结

    通过对递归算法进行了介绍,举出实例进行模拟递归的过程,递归的思想很重要,能够很好的简化负载的问题,虽然有它不足的地方,但是可以进行修改,比如对递归的出口做剪枝操作等,避免时间溢出和内存爆炸。

  • 相关阅读:
    T02 ExtractSubject 项目开发总结
    centos k8s安装dapr
    Webservice接口-WSDL文档【Webservice】
    毕业季-个人总结
    linux docker安装SqlServer2019
    HTTP、HTTPS协议详解
    2023.11.15 关于 Spring Boot 配置文件
    游戏遇到的问题
    什么是智慧型人格?智慧型性格的优缺点和职业规划
    移动Web:IIS部署 及 flexble.js 兼容
  • 原文地址:https://blog.csdn.net/dxcn01/article/details/126332863