第六章 递归算法
- 格式:ppt
- 大小:523.00 KB
- 文档页数:24
递归算法及经典例题详解
1.什么是递归
递归简单来说就是在运行过程中不断调用自己,直到碰到终止条件,返回结果的过程。
递归可以看作两个过程,分别是递和归。
递就是原问题把要计算的结果传给子问题;归则是子问题求出结果后,把结果层层返回原问题的过程。
下面设一个需要经过三次递归的问题,为大家详细看一下递归的过程:当然,现实中我们遇到递归问题是不会按照图中一样一步一步想下来,主要还是要掌握递归的思想,找到每个问题中的规律。
2.什么时候使用递归
递归算法无外乎就是以下三点:1.大问题可以拆分为若干小问题2.原问题与子问题除数据规模不同,求解思路完全相同3.存在递归终止条件
而在实际面对递归问题时,我们还需要考虑第四点:
当不满足终止条件时,要如何缩小函数值并让其进入
下一层循环中
3.递归的实际运用(阶层计算)
了解了大概的思路,现在就要开始实战了。
下面我们来看一道经典例题:
求N的阶层。
首先按照思路分析是否可以使用递归算法:
1.N!可以拆分为(N-1)!*N
2.(N-1)!与N!只有数字规模不同,求解思路相同
3.当N=1时,结果为1,递归终止
满足条件,可以递归:
publicstaticintFactorial(int num){if(num==1){return num;}return num*Factorial(num-1);}
而最后的return,便是第四步,缩小参数num的值,让递归进入下一层。
一般来说,第四步往往是最难的,需要弄清该如何缩
小范围,如何操作返回的数值,这一步只能通过不断
地练习提高了(当然如果你知道问题的数学规律也是
可以试出来的)。
简述递归算法的执行过程摘要:1.递归算法的定义和基本原理2.递归算法的执行过程3.递归算法的应用实例4.递归算法的时间复杂度和优化方法5.总结正文:递归算法是一种自调用算法,通过将问题分解为更小的子问题来解决问题。
它在计算机科学和数学领域中广泛应用,具有可读性和实用性。
下面详细介绍递归算法的执行过程、应用实例、时间复杂度和优化方法。
一、递归算法的定义和基本原理递归算法是一种算法,它通过将问题分解为更小的子问题来解决问题。
这些子问题与原始问题具有相似的特征,从而使得算法可以通过重复调用自身来解决这些子问题。
在递归算法中,有一个基本情况(base case)和递归情况(recursive case)。
基本情况是问题规模足够小,可以直接给出答案的情况;递归情况则是将问题分解为更小的子问题,并重复调用算法本身来解决这些子问题。
二、递归算法的执行过程1.初始化:定义问题的初始条件,通常是基本情况。
2.判断基本情况:如果问题规模足够小,直接给出答案。
3.划分问题:将问题分解为更小的子问题,并确保这些子问题与原始问题具有相似的特征。
4.递归调用:将子问题传递给算法本身,重复执行步骤1-3,直到基本情况出现。
5.合并结果:将递归调用返回的结果合并,得到最终答案。
三、递归算法的应用实例1.计算阶乘:递归算法可以用于计算一个正整数的阶乘。
例如,计算5的阶乘:```def factorial(n):if n == 0:return 1else:return n * factorial(n-1)```2.计算Fibonacci 数列:递归算法可以用于计算Fibonacci 数列。
例如,计算第n个Fibonacci 数:```def fibonacci(n):if n == 0:return 0elif n == 1:return 1else:return fibonacci(n-1) + fibonacci(n-2)```四、递归算法的时间复杂度和优化方法1.时间复杂度:递归算法的时间复杂度通常为O(2^n),其中n为问题的规模。
一.递归算法概述程序调用自身的编程技巧称为递归( recursion)。
一个过程或函数在其定义或说明中又直接或间接调用自身的一种方法,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量。
递归的能力在于用有限的语句来定义对象的无限集合。
用递归思想写出的程序往往十分简洁易懂。
二.递归算法的特点递归算法是一种直接或者间接地调用自身算法的过程。
在计算机编写程序中,递归算法对解决一大类问题是十分有效的,它往往使算法的描述简洁而且易于理解。
递归算法解决问题的特点:(1) 递归就是在过程或函数里调用自身。
(2) 在使用递归策略时,必须有一个明确的递归结束条件,称为递归出口。
(3) 递归算法解题通常显得很简洁,但递归算法解题的运行效率较低。
所以一般不提倡用递归算法设计程序。
(4) 在递归调用的过程当中系统为每一层的返回点、局部量等开辟了栈来存储。
递归次数过多容易造成栈溢出等。
所以一般不提倡用递归算法设计程序。
三.递归算法要求递归算法所体现的“重复”一般有三个要求:一是每次调用在规模上都有所缩小(通常是减半);二是相邻两次重复之间有紧密的联系,前一次要为后一次做准备(通常前一次的输出就作为后一次的输入);三是在问题的规模极小时必须用直接给出解答而不再进行递归调用,因而每次递归调用都是有条件的(以规模未达到直接解答的大小为条件),无条件递归调用将会成为死循环而不能正常结束。
四.例子(用从C++描述):行数程序#include <iostream>using namespace std;0 void p (int w){1 if(w>0){2 cout<<w<<" ";3 p(w-1);4 p(w-1);5 }6 }void main(){int a;cin>>a;p(a);}当输入a=4后的打印结果:当p(0)执行完了,就会执行p(1)中的语句5(所以在方格a中,填“5”)。
递归算法详解完整版递归算法是一种重要的算法思想,在问题解决中起到了很大的作用。
它通过将一个大问题划分为相同或类似的小问题,并将小问题的解合并起来从而得到大问题的解。
下面我们将详细介绍递归算法的定义、基本原理以及其应用。
首先,我们来定义递归算法。
递归算法是一种通过调用自身解决问题的算法。
它通常包括两个部分:基础案例和递归步骤。
基础案例是指问题可以被直接解决的边界情况,而递归步骤是指将大问题划分为较小问题并通过递归调用自身解决。
递归算法的基本原理是"自顶向下"的思维方式。
即从大问题出发,不断将问题划分为较小的子问题,并解决子问题,直到达到基础案例。
然后将子问题的解合并起来,得到原始问题的解。
递归算法的最大特点是简洁而优雅。
通过将复杂问题分解为简单问题的解决方式,可以大大减少代码的复杂程度,提高程序的效率和可读性。
但是递归算法也有一些缺点,包括递归深度的限制和复杂度的不确定性。
过深的递归调用可能导致栈溢出,而不合理的递归步骤可能导致复杂度过高。
递归算法有许多应用场景,我们来介绍其中一些典型的应用。
1.阶乘问题:计算一个数的阶乘。
递归算法可以通过将问题划分为更小的子问题来解决。
例如,n的阶乘可以定义为n乘以(n-1)的阶乘。
当n 等于1时,我们可以直接返回1作为基础案例。
代码如下:```int factorial(int n)if (n == 1)return 1;}return n * factorial(n - 1);```2.斐波那契数列问题:求斐波那契数列中第n个数的值。
斐波那契数列的定义是前两个数为1,然后从第三个数开始,每个数都是前两个数的和。
递归算法可以通过将问题划分为两个子问题来解决。
当n等于1或2时,直接返回1作为基础案例。
代码如下:```int fibonacci(int n)if (n == 1 , n == 2)return 1;}return fibonacci(n - 1) + fibonacci(n - 2);```3.二叉树问题:对于给定的二叉树,递归算法可以通过递归调用左子树和右子树的解来解决。
递归算法递推公式求解递归算法是一种自我调用的算法,它通过不断将问题分解为更小的子问题来求解问题。
递归算法的核心是递推公式,也称为递归式,它描述了如何将问题分解为子问题,并如何从子问题的解中得到原问题的解。
递推公式通常具有以下形式:T(n) = aT(n/b) + f(n)其中,T(n) 表示问题规模为n 时的时间复杂度,a 表示每次递归调用的次数,b 表示每次递归调用后问题规模缩小的比例,f(n) 表示除了递归调用外的其他操作的时间复杂度。
为了求解递推公式,我们可以使用以下方法:1.迭代法:通过迭代递推公式的方式逐步计算出T(n) 的值。
这种方法比较直观,但对于较大的n 值,迭代次数可能非常多,计算量也会非常大。
2.替换法:通过猜测T(n) 的形式,并将其代入递推公式中进行验证。
如果猜测正确,则可以得到T(n) 的解。
这种方法需要对问题有一定的了解和猜测能力。
3.大师定理:大师定理是一种求解递推公式的通用方法。
它可以根据递推公式的形式,直接给出T(n) 的时间复杂度。
大师定理有多种形式,其中最常用的是以下三种:a. 如果f(n) = O(n^c),其中c < log_b(a),则T(n) = O(n^log_b(a))。
b. 如果f(n) = O(n^c),其中c = log_b(a),则T(n) = O(n^c * log_n)。
c. 如果f(n) = O(n^c),其中c > log_b(a),且对于所有足够大的n,有af(n/b) <= f(n),则T(n) = O(f(n))。
需要注意的是,大师定理只是一种求解递推公式的工具,它并不能解决所有类型的递推公式。
在实际应用中,我们需要根据具体问题选择合适的求解方法。
离散数学中递归算法的工作原理解析离散数学是一门研究离散对象和离散结构的数学学科,其在计算机科学中有着广泛的应用。
递归算法是离散数学中的一个重要概念,本文将对递归算法的工作原理进行解析。
1. 递归算法的定义递归算法是一种通过反复调用自身来解决问题的算法。
它通常包含了一个递归出口(基本情况)和一个递归体(递归情况)。
当问题达到递归出口时,算法停止递归并返回结果。
否则,算法继续递归调用自身,将问题分解为规模更小的子问题,并在子问题上进行递归求解。
2. 递归算法的优点与注意事项递归算法具有以下优点:1) 逻辑清晰简洁:递归算法能够使用简洁的方式描述问题的解决过程。
2) 结构灵活:递归算法能够解决各种类型的问题,适用范围广泛。
然而,递归算法也需要注意以下事项:1) 递归深度:递归算法的性能与问题的规模成反比。
递归深度过大可能导致栈溢出或性能下降。
2) 重复计算:递归算法中可能存在重复计算,增加了计算量。
可以使用记忆化技术(如动态规划)来优化递归算法。
3. 递归算法的应用场景递归算法在计算机科学中有广泛的应用,包括但不限于以下领域:1) 数据结构:递归算法常用于处理树、图、链表等数据结构,如树的遍历、图的深度优先搜索等。
2) 排列组合:递归算法可以用于生成排列组合,如全排列、组合数等。
3) 分治算法:分治算法通常使用递归来将问题分解为更小的子问题,并分别求解。
4. 递归算法的实现步骤实现一个递归算法通常包括以下步骤:1) 定义递归出口:确定递归算法何时停止递归,返回结果。
2) 确定递归体:根据问题的特点,将问题分解为规模更小的子问题,并调用自身来解决子问题。
3) 设计递归调用:根据子问题的规模和性质,设计递归调用的方式。
4) 处理子问题的结果:将子问题的结果合并得到原问题的结果。
5. 递归算法的示例:阶乘计算下面通过计算阶乘的例子来具体说明递归算法的工作原理:```python# 递归算法计算阶乘def factorial(n):if n == 0:return 1else:return n * factorial(n-1)```上述代码中,factorial函数通过递归来计算阶乘。