深入理解递归函数.docx

合集下载

递归算法知识点总结

递归算法知识点总结

递归算法知识点总结一、基本概念递归算法的基本概念是基于递归函数的思想。

递归函数是一个调用自身的函数。

递归算法通常可以分为两种类型:简单递归和复杂递归。

简单递归是指在递归函数中直接调用自身,而复杂递归则是指在递归函数中可能会有多个递归调用。

递归算法通常用于解决可以分解为若干子问题的问题,这种方法通常可以更加简洁地解决问题,但同时也可能会带来一些计算复杂度的问题。

递归算法的设计通常包括以下几个步骤:1. 确定基本情况:在设计递归函数时,通常需要确定一个或多个基本情况。

基本情况通常是指在递归函数中不需要再次调用自身的情况。

2. 确定递归情况:在设计递归函数时,需要确定一个或多个递归情况。

递归情况通常是指在递归函数中需要调用自身的情况。

3. 确定递归方式:当确定了递归函数的基本情况和递归情况之后,就需要确定递归函数的调用方式。

通常有两种方式:直接递归和间接递归。

4. 编写递归函数:根据确定的基本情况、递归情况和递归方式,编写递归函数。

5. 测试递归函数:编写递归函数后,需要对递归函数进行测试,确保递归函数能够正确地解决问题。

二、递归算法的原理递归算法的原理是基于递归函数的调用。

当一个递归函数被调用时,它会将自身的执行环境保存到栈中,并且在栈中分配一些空间。

在递归函数中,如果有一些局部变量,这些变量会在栈中分配空间。

随着递归函数的深入调用,栈中的空间也会不断增加。

在递归函数的执行过程中,通常需要考虑递归栈的压栈和出栈操作。

在递归函数被调用时,会执行一些初始化操作,并将递归参数保存到栈中。

在递归函数中,如果遇到递归情况,会再次调用自身,并且将自身的执行环境保存到栈中。

在递归函数的执行过程中,如果遇到基本情况,就会结束当前递归调用,并且从栈中释放空间。

递归算法的原理是基于递归函数的深度调用的。

当递归函数被调用时,会执行一些初始化过程,并将递归参数保存到栈中。

当递归函数执行完毕后,会从栈中释放空间。

在递归函数的执行过程中,栈中的空间会不断增加和释放。

递归的深度理解

递归的深度理解

递归的深度理解1、递归的理解•一个方法在执行的过程中调用自身,就称为“递归”,其中递归要满足有一个趋于终止的条件•可以类比于数学上的“数学归纳”,有一个起始条件,还有一个递推公式•可以拆分为“递”和“归”这两个过程举个例子:当你在电影院看电影,由于太黑你们都就近找了位置直接坐下,但你需要直到这是第几排,于是你就会问前面的兄弟,然后等待回答,前排的兄弟可能不知道,于是又去问了他前排的兄弟并等待回答…就这样直到问道有一个兄弟知道到自己的排数,递的过程就完成了,知道排数的这个兄弟就会把他的排数传给后排问他的人,这下后排的人就接收到了前排的结果,通过计算就知道了自己的排数,然后再把自己的排数告诉他后排的人…直到你最后通过前排的结果算出自己的位置。

通过这个例子来总结几个点•后排的兄弟在开始问前排,这就是一次“递”•这个前排的人一旦被问道,他就要在栈上开辟一块内存空间来保存后排人的问题•这个前排兄弟不知道他的排数,再向前问,并等待前排回答,这就是他这块内存里还保存着数据,并且这个等待就表明方法并未执行完毕,他在等待下一排返回结果•总有一排的兄弟直到自己的排数,这个知道自己排数的兄弟就是递归的终止条件。

•知道排数的兄弟把结果返回上一排,上一排经过计算就再次返回,这就是归的过程,每个栈内存在接到结果后才执行完毕并返回结果。

2、图解过程分析//递归求N!,加上日志打印(递归的调试)public static void main(String[] args){int n = 4;int ret = factor(n);System.out.println('ret = '+ret);}public static int factor(int n){System.out.println('函数开始,n = '+n);if(n==1){System.out.println('函数结束,n=1 ret=factor(1)=1'); return 1;}int ret = n*factor(n-1);System.out.println('函数结束,n = '+n +“ret = ”+ret);return ret;}//执行结果函数开始,n = 4函数开始,n = 3函数开始,n = 2函数开始,n = 1函数结束,n =1 ret = 1函数结束,n =2 ret = 2函数结束,n =3 ret = 6函数结束,n =4 ret = 24ret = 243、递归解决问题一般当同时满足以下三个条件就可以用递归来解决1.一个问题可以分解成几个子问题2.就是一个大的数据规模问题可以分解成数据规模更小的问题,就比如你要知道自己在那一排就分为了很多个前一排在哪一排的问题。

C语言递归函数

C语言递归函数

C语言递归函数C语言是一种非常重要的编程语言,递归函数是C语言中的一个重要概念。

本文将详细介绍C语言递归函数的定义、实现以及递归函数的优缺点。

1. 递归函数的定义在C语言中,递归函数是指在函数内部调用自身的函数。

递归函数通常包含一个或多个基准情况(递归终止条件),在满足基准情况之前,递归函数会不断调用自身来解决更小规模的问题。

2. 递归函数的实现为了实现递归函数,我们需要考虑两个重要的要素:基准情况和递归关系。

2.1 基准情况在编写递归函数时,必须确定递归终止条件。

这个条件通常是问题规模足够小,可以直接得出答案的情况。

通过设置基准情况,可以避免递归函数陷入无限循环,导致程序崩溃。

2.2 递归关系递归关系指的是将原始问题拆分为更小规模的子问题,并且这些子问题与原问题的解具有相同的结构。

递归函数通过调用自身来解决子问题,将子问题的解合并为原问题的解。

递归关系的正确定义是确保递归函数能够有效地解决问题的关键。

3. 递归函数的示例下面是一个计算斐波那契数列的递归函数的示例:```c#include <stdio.h>int fibonacci(int n){if(n <= 1) // 基准情况return n;else // 递归关系return fibonacci(n-1) + fibonacci(n-2);}int main(){int n = 10;int result = fibonacci(n);printf("斐波那契数列的第%d项为%d\n", n, result); return 0;}```在以上示例中,递归函数fibonacci计算了斐波那契数列的第n项。

当n小于等于1时,即为基准情况,直接返回n。

否则,递归调用fibonacci函数计算第n-1和第n-2项,并将结果相加返回。

4. 递归函数的优缺点递归函数具有以下优点:- 可以简化代码实现,使代码更加简洁易读。

递归小总结

递归小总结

递归小总结什么是递归?递归是一种程序设计技巧,在一个函数中调用自身来解决问题。

换句话说,递归是通过把一个问题分解成更小的子问题来解决复杂问题的方法。

递归的原理递归算法的核心思想是将一个大问题分解成一个或多个与原问题类似但规模更小的子问题。

递归函数通过调用自身来解决这些子问题,直到子问题变得足够简单,可以直接求解。

递归函数会一层一层地调用自身,直到达到结束条件结束递归。

递归的基本要素递归函数通常需要包含以下几个基本要素:1.基准条件(基础案例):递归函数需要定义在何时结束递归的条件。

当满足基准条件时,递归将不再进行,而是返回一个最终结果。

2.递归调用:递归函数在处理问题时,会将原问题分解成一个或多个较小的子问题。

为了解决这些子问题,递归函数需要调用自身。

3.问题拆解:递归函数需要根据原问题,将其分解成与原问题类似但规模更小的子问题。

4.合并结果:递归函数需要将子问题的结果合并起来,得到原问题的解。

递归的优缺点递归的优点在于它能够清晰地表达问题的解决思路,简化代码的编写。

在某些问题中,使用递归能够使代码更加简洁易懂。

然而,递归也存在一些缺点。

首先,递归函数的调用过程是逐层深入的,这会占用大量的内存,如果递归的层数过多,可能会导致栈溢出。

此外,递归函数的执行效率通常较低,因为每一次递归调用都会增加函数调用的开销。

递归的应用场景递归算法广泛应用于各种领域,特别是数学、计算机科学和算法设计中。

以下是一些常见的递归应用场景:1.阶乘计算:计算一个正整数的阶乘可以使用递归来实现,如factorial(n) = n * factorial(n-1)。

2.斐波那契数列:斐波那契数列是一个递归定义的数列,其中每一项等于前两项的和。

递归函数可以用来计算斐波那契数列的第 n 项。

3.二叉树遍历:对于二叉树的遍历,可以使用递归来实现前序、中序和后序遍历。

4.文件夹遍历:对于文件夹中的文件和子文件夹,可以使用递归来遍历整个文件目录树。

递归函数解释

递归函数解释

递归函数解释
一、递归定义
递归函数是指一个函数在其定义域内,存在某个或某些子集作为其自身的输入,也就是一个函数直接或间接调用自身的一种过程。

通常递归函数的定义会包含两部分:基本情况和递归情况。

二、基本情况
基本情况也被称为基线条件,是递归函数的结束条件。

基本情况决定了递归何时停止,它必须是直接可求解的情况。

基本情况是递归函数的根,其他递归情况都由它导出。

三、递归转化
递归转化是将问题转化为更小的同类问题的一种策略。

在递归函数中,每一个递归调用都是为了解决一个更小的子问题,以便于通过这些子问题的解来找到原问题的解。

四、递归终止
递归终止是指函数在完成一系列递归调用后,最终达到基本情况并返回结果的过程。

递归终止是递归函数的终点,也是递归函数开始返回结果的地方。

五、递归层次
递归层次是指函数在执行过程中所经历的递归深度。

每一个递归调用都会增加一层的递归深度,直到达到基本情况并返回结果,然后开始逐层返回,直到完成所有递归调用。

理解递归层次有助于更好地理解递归函数的执行过程和时间复杂度。

机械原理 递归函数

机械原理 递归函数

机械原理递归函数机械原理中,递归函数是一种十分重要的概念。

递归函数指的是函数在执行时会自我调用的一种函数。

这种自我调用的机制可以让我们在处理一些复杂问题时,可以通过递推的方式来解决。

递归函数的基本原理是将一个大问题分解为若干个小问题来进行求解。

接着,将这些小问题通过递归函数自我调用来逐个求解,最后再合并起来,得出整个问题的解。

我们对于一个数列进行排序,可以采用递归函数来实现。

将整个数列分解为两个部分来进行排序,随后对这两个部分再进行分解。

递归函数在不断地调用自身的情况下,将整个数列分解为一个个单独的元素,再将这些单独的元素依次进行排序,最后再通过递归函数将这些部分合并起来,得到最终的结果。

递归函数的优点在于可以大大简化程序开发的工作量,可以将大问题分解为小问题来进行处理。

递归函数也可以使代码更加易于阅读和理解,降低程序开发的难度。

递归函数也有其缺点,其主要是由于递归函数的自我调用机制会导致函数栈的不断增长,从而导致内存的消耗。

在使用递归函数的时候要谨慎,最好在程序中加入限制条件。

递归函数还有一些需要注意的问题。

在使用递归函数时,一定要注意递归深度的控制,不能无限制地调用自身,否则会导致死循环。

在编写递归函数时,一定要注意递归结束条件的设置,否则也会导致死循环。

递归函数在机械原理中具有十分重要的地位,可以帮助我们更加高效地解决复杂的问题。

在使用递归函数时,要注意一些需要注意的问题,这样才能更好地发挥递归函数的优点,避免其缺点的影响。

除了以上提到的注意事项,递归函数在机械原理中还有其它的一些应用。

在图形学和计算机科学领域,递归函数被广泛应用于分形图形的绘制中。

分形图形通常具有自相似性的特点,即这个图形的一部分可以看作是整个图形的缩小版。

可以通过递归的方式来绘制分形图形。

在每次递归时,将这个图形分成若干个部分,再在每个部分内部递归地进行绘制。

最终将所有的小部分拼接起来,即可得到整个分形图形。

在机器人控制和路径规划中,递归函数也被广泛地应用。

递归函数详细讲解

递归函数详细讲解

递归函数详细讲解
(实用版)
目录
1.递归函数的定义和特点
2.递归函数的执行过程
3.递归函数的应用实例
4.递归函数的优缺点
正文
递归函数是一种在函数体内部调用自身的函数。

它能够实现一些具有重复性的任务,通过将大问题分解成小问题来解决问题。

递归函数的特点是函数体内部存在一个递归调用,通常是一个条件判断和一个递归调用组成。

递归函数的执行过程是先判断条件,如果满足条件就进行递归调用,否则执行其他操作。

递归函数在实际应用中非常广泛。

例如,计算阶乘、汉诺塔问题、斐波那契数列等都是典型的递归函数应用实例。

这些例子中,递归函数通过将大问题分解成小问题,然后通过解决小问题来解决大问题。

递归函数的优点是可以将复杂的问题简化为较小的、更易于解决的问题,而且递归函数的代码通常比较简洁。

但是,递归函数也存在一些缺点。

首先,递归函数的运行效率较低,因为需要进行多次函数调用和返回。

其次,递归函数的深度过大可能导致栈溢出,造成程序崩溃。

总的来说,递归函数是一种非常有用的编程技巧,能够解决许多复杂的问题。

第1页共1页。

《第11课简单的递归》教学设计教学反思-2023-2024学年小学信息技术人教版三起01六年级上册

《第11课简单的递归》教学设计教学反思-2023-2024学年小学信息技术人教版三起01六年级上册

《简单的递归》教学设计方案(第一课时)一、教学目标1. 理解递归的概念,了解递归在计算机编程中的运用。

2. 掌握简单的递归函数,能够进行递归函数的调用和调试。

3. 通过实践操作,培养学生的逻辑思维能力和问题解决能力。

二、教学重难点1. 教学重点:掌握简单的递归函数,能够进行递归函数的调用。

2. 教学难点:理解递归的概念,培养逻辑思维能力和问题解决能力。

三、教学准备1. 准备教学课件和相关代码示例。

2. 准备计算机设备和网络环境。

3. 安排学生进行课前预习,了解递归的基本概念。

4. 设计递归函数实践操作任务,以便学生能够动手实践,加深理解。

四、教学过程:1. 导入新课:教师通过一个简单的递归问题引入课题,激发学生的学习兴趣。

2. 讲解递归概念:教师详细解释递归的基本概念,包括递归函数、递归调用等。

可以通过一些简单的例子帮助学生理解。

3. 问题分析:教师提出一个具体的递归问题,引导学生进行分析,理解递归解决问题的思路和方法。

4. 代码实现:教师展示一段简单的递归代码,并逐步解释代码的每一行,帮助学生理解递归的实现过程。

学生可以在电脑上尝试编写自己的递归代码,进行实践操作。

5. 小组讨论:学生以小组形式进行讨论,分享各自的递归代码实现过程和遇到的问题,互相学习,共同进步。

6. 教师点评与反馈:教师对学生的代码进行点评,给予鼓励和支持,指出存在的问题和改进方向。

同时,教师也可以提出一些更复杂的问题,引导学生深入思考递归的应用。

7. 课堂小结:教师对本节课的内容进行总结,强调递归思想和方法的重要性,鼓励学生多加实践,提高解决问题的能力。

8. 布置作业:学生回家后尝试解决一些更复杂的递归问题,巩固所学知识。

四、课后反思教师在课后需要对本节课的教学过程进行反思,总结成功经验和需要改进的地方,为今后的教学提供参考。

同时,教师也可以与学生进行交流,了解他们对本节课的感受和收获,从而更好地指导今后的学习。

教学设计方案(第二课时)一、教学目标1. 理解递归的概念,了解递归在计算机编程中的用途。

递归函数名词解释

递归函数名词解释

递归函数名词解释
递归函数是指在一个函数的定义中又调用了该函数本身的情况。

递归函数在程序设计中起着非常重要的作用,能够简化程序的结构,提高代码的可读性和可维护性。

递归函数通常用于解决问题的分而治之,将一个大问题分解成几个小问题,通过递归调用来解决这些小问题,最终达到解决整个大问题的目的。

在递归函数中,需要定义一个基本情况,也就是递归的结束条件,否则函数会陷入无限循环,无法正常结束。

当函数遇到基本情况时,递归调用将停止,函数返回结果。

递归函数的基本情况可以看作是递归的出口,也是问题被解决的最小单元。

递归函数可以直接或间接地调用自身,直接递归是指函数在自身的定义中直接调用自身,间接递归是指函数在调用其他函数的过程中间接地调用自身。

无论是直接递归还是间接递归,都需要小心处理递归调用的次数,以免造成栈溢出或者程序性能下降的问题。

递归函数在编程中有许多应用,比如在树的数据结构中,可以使用递归函数来遍历树的节点;在计算数学问题中,如斐波那契数列等,也可以使用递归函数来解决;在图形学中,递归函数可以用来绘制分形图形等。

总的来说,递归函数是一种非常有用的编程技巧,能够简化程序的结构,提高代码的可读性和可维护性。

但是在使用递归函数时需要小心处理递归调用的次数,避免陷入无限循环的情况。

递归函数的正确使用将会极大地丰富程序设计的思路和方法,提高程序的效率和可扩展性。

了解递归函数的原理和用途

了解递归函数的原理和用途

了解递归函数的原理和用途递归函数是计算机编程中一种重要的技术,它能够解决许多复杂的问题。

在本文中,我们将深入探讨递归函数的原理和用途,以帮助读者更好地理解和应用这一概念。

一、递归函数的原理递归函数是指在函数定义中调用自身的函数。

它通过不断地将问题分解为更小的子问题来解决复杂的计算任务。

递归函数通常包含两个部分:基本情况和递归情况。

基本情况是指递归函数能够直接解决的简单问题。

当函数的输入达到基本情况时,递归将停止,函数将返回一个结果。

递归情况是指函数在未达到基本情况时,通过调用自身来解决更小的子问题。

通过不断地调用自身,递归函数能够将复杂的问题分解为简单的子问题,并最终得到解决。

递归函数的关键在于找到递归情况和基本情况之间的关系,确保每次递归调用都能够使问题规模减小,最终达到基本情况。

二、递归函数的用途递归函数在计算机编程中有广泛的应用。

以下是一些常见的用途:1. 数学计算:递归函数可以用于解决数学问题,如计算斐波那契数列、阶乘等。

通过将问题分解为更小的子问题,递归函数能够高效地计算出结果。

2. 数据结构操作:递归函数可以用于对各种数据结构进行操作,如二叉树的遍历、图的搜索等。

通过递归调用,可以轻松地对数据结构进行遍历和操作。

3. 字符串处理:递归函数可以用于处理字符串,如反转字符串、检测回文等。

通过将字符串分解为字符子串,递归函数能够高效地处理各种字符串操作。

4. 文件系统操作:递归函数可以用于对文件系统进行操作,如遍历文件夹、搜索文件等。

通过递归调用,可以方便地对文件系统进行深度优先搜索。

5. 解决复杂问题:递归函数可以用于解决各种复杂的问题,如迷宫问题、八皇后问题等。

通过将问题分解为更小的子问题,递归函数能够高效地找到问题的解决方案。

三、递归函数的优缺点递归函数具有一些显著的优点,也存在一些缺点。

优点:1. 简洁性:递归函数能够用较少的代码解决复杂的问题,使代码更加简洁易读。

2. 可读性:递归函数能够直观地表达问题的分解和解决过程,提高代码的可读性。

递归的理解

递归的理解

递归的理解
递归是一种算法或编程技巧,它通过自身调用来解决问题,常常被用来处理具有递归结构的问题。

在递归中,一个函数或子程序会重复调用自身,直到达到终止条件为止。

递归的理解需要注意以下几个方面:
首先,递归必须有一个终止条件,否则会陷入死循环。

终止条件是指递归应该停止的条件,一旦达到这个条件,递归就会结束。

其次,在递归过程中,每一级递归都需要相同的处理方式。

也就是说,每次递归都要按照同样的逻辑进行处理,直到达到终止条件。

第三,在递归中,每次调用都会有一定的开销,包括函数调用、参数传递和栈空间的分配等。

因此,在使用递归时,需要注意内存的使用和性能的优化。

最后,递归常常被用来解决复杂的问题,例如快速排序、归并排序、二叉树的遍历等。

但是,如果不恰当地使用递归,会导致栈溢出等问题。

因此,在使用递归时,需要仔细考虑其适用性和实现方式。

总之,递归是一种非常有用的算法思想,理解递归需要掌握其基本原理和注意事项,才能正确地应用到实际问题中。

- 1 -。

【C】函数递归算法讲解

【C】函数递归算法讲解

【C】函数递归算法讲解在数学与计算机科学中,递归算法是指在函数的定义中使用函数自身的方法。

在程序中,递归是通过函数的调用来实现的。

函数直接调用其自身,称为直接递归;函数间接调用其自身,称为间接递归。

在函数定义中,其内部操作又直接或间接地调用了自身,则称这样的函数为递归函数。

生活中我们也存在这样的递归现象,比如:从前有座山,山里有个庙,庙里有个老和尚和一个小和尚。

一天,老和尚在对小和尚讲故事,故事的内容是:从前有座山,山里有个庙,庙里有个老和尚和一个小和尚。

一天,老和尚在对小和尚讲故事,故事的内容是:从前有座山,山里有个庙,庙里有个老和尚和一个小和尚。

一天,老和尚在对小和尚讲故事,故事的内容是……故事中又调用了这个故事正如函数中又调用了这个函数一样。

•••••••••••#include<iostream>using namespace std;int f()//自定义函数{ return f();}int main()//主函数 { cout<<f();//函数调用 return 0;} 但上述函数的定义是不合理的,因为递归函数和生活中的递归现象具有不同之处:生活中有些递归现象可以无限递归,但递归函数必须有递归终止条件。

所以,递归函数有两大要素:①递归关系式:对问题进行递归形式的描述。

②递归终止条件:当满足该条件时以一种特殊情况处理而不是用递归关系式处理。

参考程序:••••••••••••••••••#include<iostream>using namespace std;void output(int n)//自定义函数 { if(n==1) cout<<1<<' ';//递归终止条件 else//递归关系式 { output(n-1); cout<<n<<' '; } }int main()//主函数{ int n; cin>>n; output(n);//函数调用 return 0;}参考程序:•••••••••••••#include<iostream>using namespace std;int sum(int n)//自定义函数 { if(n==1) return 1;//递归终止条件 else return n+sum(n-1);//递归关系式}int main()//主函数{ int n; cin>>n; cout<<sum(n);//函数调用 return 0;}参考程序:•••••••••••••#include<iostream>using namespace std;int jc(int n)//自定义函数 { if(n==1) return 1;//递归终止条件 else return n*jc(n-1);//递归关系式 }int main()//主函数 { int n; cin>>n; cout<<jc(n);//函数调用 return 0;}参考程序:••••••••••••••#include<iostream>using namespace std;int xn(int x,int n)//自定义函数 { if(n==0) return 1;//递归终止条件 else return x*xn(x,n-1);//递归关系式}int main()//主函数{ int x,n; cin>>x>>n; cout<<xn(x,n);//函数调用 return 0;}参考程序:•••••••••••••#include<iostream>using namespace std;int f(int n)//自定义函数 { if(n<=1) return n;//递归终止条件 else return f(n-1)+f(n-2);//递归关系式 }int main()//主函数 { int n; cin>>n; for(int i=0;i<=n;i++) cout<<f(i)<<' ';//函数调用 return 0;}••••••••••••••#include<iostream>using namespace std;int gcd(int m,int n)//自定义函数 { if(m%n==0) return n;//递归终止条件 else returngcd(n,m%n);//递归关系式}int main()//主函数{ int m,n; cin>>m>>n; cout<<gcd(m,n);//函数调用 return 0;}••••••••••••••••••••••••••#include<iostream>using namespace std;int a[20];bool flag;//利用全局变量falg传递结果void judge(int n,int m)//自定义函数{ if(a[n]==m) flag=true;//递归终止条件else if (n==1) return;//递归终止条件 else//递归关系式 { judge(n-1,m-a[n]); judge(n-1,m); }}int main()//主函数 { int n,m; cin>>n; for (int i=1; i<=n; ++i) cin>>a[i]; cin>>m; flag=false; judge(n,m);//函数调用if (flag) cout<<'YES'<<endl; else cout<<'NO'<<endl; return 0;}••••••••••••••••••••••••#include<iostream>#include<cmath>using namespace std;int sum;void res(int a,int y)//自定义函数{ for(int i=y;i<=sqrt(a);i++) { if(a%i==0) res(a/i,i); } sum++;}int main()//主函数{ int n,a; cin>>n; while(n--) { cin>>a; sum=0; res(a,2); cout<<sum<<endl; } return 0;}••••••••••••••#include<iostream>using namespace std;int f(int n)//自定义函数 { if(n==1) return 1;//递归终止条件 else return 2*f(n-1)+1;//递归关系式}int main()//主函数 { int n; cin>>n; cout<<f(n);//函数调用 return 0;}•••••••••••••••••••#include<iostream>using namespace std;int step=0;//步数void hanoi(int n,char a,char b,char c)//自定义函数{ if(n==1) cout<<'第'<<++step<<'步:'<<'将圆盘'<<n<<'从'<<a<<'移动到'<<c<<endl; else { hanoi(n-1,a,c,b); cout<<'第'<<++step<<'步:'<<'将圆盘'<<n<<'从'<<a<<'移动到'<<c<<endl; hanoi(n-1,b,a,c); } }int main()//主函数 { int n; cin>>n; hanoi(n,'A','B','C');//函数调用 return 0;}。

递归函数_精品文档

递归函数_精品文档

递归函数什么是递归函数?在编程中,递归函数是一种直接或间接地调用自身的函数。

递归在很多算法和数据结构中都有广泛的应用,它能够简化问题的解决步骤并提高代码的可读性。

使用递归函数时,我们只需要关注当前步骤的解决方式,而不需要关心前面步骤的细节。

递归的基本原理递归函数的基本原理是将一个大问题划分为一个或多个相似的小问题,并通过解决这些小问题来解决整个大问题。

递归函数的定义通常包含两个部分: 1. 基线条件:当问题达到基线条件时,递归将停止。

这是递归函数的出口,也是递归函数中没有再次调用自身的终止点。

2. 递归条件:当问题未达到基线条件时,递归函数将调用自身来处理子问题。

递归函数的示例下面我们通过一些示例来说明递归函数的使用方法。

示例一:计算阶乘def factorial(n):if n ==0:return1else:return n * factorial(n-1)在这个示例中,我们定义了一个递归函数factorial(),它用于计算一个非负整数的阶乘。

如果输入参数n的值为0,则函数返回1;否则,函数返回n乘以factorial(n-1)的结果。

通过逐步调用factorial()函数,我们最终可以得到所需的阶乘值。

示例二:计算斐波那契数列def fibonacci(n):if n <=1:return nelse:return fibonacci(n-1) + fibonacci(n-2)斐波那契数列是一个经典的递归问题。

在上面的示例中,我们定义了一个递归函数fibonacci(),它用于计算斐波那契数列中第n个数的值。

如果n的值小于等于1,则直接返回n;否则,返回fibonacci(n-1)和fibonacci(n-2)的和。

通过逐步调用fibonacci()函数,我们可以得到斐波那契数列中任意位置的数值。

递归函数的优缺点递归函数有以下几个优点: 1. 递归函数可以简化问题的解决步骤,使代码更加简洁易懂。

递归函数实验报告心得

递归函数实验报告心得

一、实验背景在本次实验中,我们学习了递归函数的概念、原理以及应用。

递归函数是一种在函数内部调用自身的方法,它能够解决许多复杂的问题,具有简洁、直观的特点。

通过本次实验,我对递归函数有了更深入的了解,以下是我对实验的心得体会。

二、实验内容1. 实验目的通过本次实验,掌握递归函数的定义、原理和应用,能够运用递归函数解决实际问题。

2. 实验原理递归函数是一种在函数内部调用自身的方法,其特点是函数自身作为子问题解决者。

递归函数由两部分组成:递归基准和递归步骤。

(1)递归基准:当问题规模足够小,可以直接求解时,递归基准给出了问题的直接解。

(2)递归步骤:将原问题转化为一个规模较小的子问题,然后递归调用自身来求解。

3. 实验内容本次实验主要涉及以下几个递归函数的编写和测试:(1)计算阶乘(2)打印整数各位数(3)计算斐波那契数列(4)逆序输出字符串(5)汉诺塔问题三、实验过程及心得1. 阶乘函数在编写阶乘函数时,我首先确定了递归基准,即当n=1时,阶乘为1。

然后根据递归步骤,将原问题转化为计算n-1的阶乘,并将结果乘以n。

通过不断递归调用自身,最终得到n的阶乘。

心得:在编写递归函数时,要注意递归基准和递归步骤的确定,确保函数能够正确收敛。

2. 打印整数各位数该函数通过不断取余和整除操作,将整数拆分为各个位数,并逆序打印。

心得:在编写递归函数时,要注意处理好输入参数和返回值,确保函数逻辑正确。

3. 计算斐波那契数列斐波那契数列是一个经典的递归问题,通过递归调用自身,可以得到数列的任意项。

心得:在编写递归函数时,要注意优化递归过程,避免重复计算。

4. 逆序输出字符串该函数通过递归调用自身,将字符串的第一个字符输出,然后对剩余的字符串进行递归处理。

心得:在编写递归函数时,要注意处理边界条件,确保函数能够正确执行。

5. 汉诺塔问题汉诺塔问题是一个经典的递归问题,通过递归调用自身,将n-1个盘子移动到目标位置,然后将剩余的盘子移动到目标位置。

函数递归实验报告

函数递归实验报告

函数递归实验报告函数递归实验报告引言:函数递归是计算机科学中一种重要的概念,它可以简化问题的解决过程,使得代码更加简洁和易读。

通过递归,一个函数可以调用自身,从而实现对问题的不断分解和求解。

本实验旨在通过实际的例子,深入探究函数递归的原理和应用。

一、递归的基本原理递归的基本原理是将一个大问题分解为若干个相同或类似的子问题,通过解决子问题来解决整个问题。

在函数递归中,递归函数会调用自身,每次调用时传入不同的参数,直到达到某个终止条件,然后逐层返回结果,最终得到问题的解。

二、递归的经典应用——阶乘函数阶乘函数是函数递归的经典应用之一。

它的定义如下:```def factorial(n):if n == 0 or n == 1:return 1else:return n * factorial(n-1)```在上述代码中,当n等于0或1时,阶乘的结果为1;否则,阶乘的结果为n乘以(n-1)的阶乘。

通过递归调用,可以简洁地实现阶乘的计算。

三、递归的实际应用——斐波那契数列斐波那契数列是另一个经典的递归应用。

它的定义如下:```def fibonacci(n):if n == 0:return 0elif n == 1:return 1else:return fibonacci(n-1) + fibonacci(n-2)```在上述代码中,当n等于0时,斐波那契数列的结果为0;当n等于1时,结果为1;否则,结果为前两个数的和。

通过递归调用,可以方便地计算出斐波那契数列的第n项。

四、递归的优缺点函数递归的优点在于可以简化问题的解决过程,使得代码更加清晰和易于理解。

递归的思想符合人类的思维方式,能够将复杂的问题分解为简单的子问题,从而降低解决问题的难度。

然而,递归也存在一些缺点,比如递归调用可能会消耗较多的内存和时间,当递归的层数过多时,可能会导致栈溢出的问题。

五、递归的应用场景函数递归在实际开发中有着广泛的应用场景。

深入理解递归

深入理解递归

深⼊理解递归递归的思想以此类推是递归的基本思想。

具体来讲就是把规模⼤的问题转化为规模⼩的相似的⼦问题来解决。

在函数实现时,因为解决⼤问题的⽅法和解决⼩问题的⽅法往往是同⼀个⽅法,所以就产⽣了函数调⽤它⾃⾝的情况。

另外这个解决问题的函数必须有明显的结束条件,这样就不会产⽣⽆限递归的情况了。

递归的两个条件可以通过递归调⽤来缩⼩问题规模,且新问题与原问题有着相同的形式。

(⾃⾝调⽤)存在⼀种简单情境,可以使递归在简单情境下退出。

(递归出⼝)递归算法的⼀般形式:func( mode){if(endCondition){ //递归出⼝end;}else{func(mode_small) //调⽤本⾝,递归}}求⼀个数的阶乘是练习简单⽽典型的例⼦,阶乘的递推公式为:factorial(n)=n*factorial(n-1),其中n为⾮负整数,且0!=1,1!=1我们根据递推公式可以轻松的写出其递归函数:public static long factorial(int n) throws Exception {if (n < 0)throw new Exception("参数不能为负!");else if (n == 1 || n == 0)return 1;elsereturn n * factorial(n - 1);}递归的过程在求解6的阶乘时,递归过程如下所⽰。

我们会惊奇的发现这个过程和栈的⼯作原理⼀致对,递归调⽤就是通过栈这种数据结构完成的。

整个过程实际上就是⼀个栈的⼊栈和出栈问题。

然⽽我们并不需要关⼼这个栈的实现,这个过程是由系统来完成的。

那么递归中的“递”就是⼊栈,递进;“归”就是出栈,回归。

我们可以通过⼀个更简单的程序来模拟递进和回归的过程:/*** 关于递归中递进和回归的理解* @param n*/public static void recursion_display(int n) {int temp=n;//保证前后打印的值⼀样System.out.println("递进:" + temp);if (n > 0) {recursion_display(--n);}System.out.println("回归:" + temp);}递归的例⼦斐波那契数列斐波那契数列的递推公式:Fib(n)=Fib(n-1)+Fib(n-2),指的是如下所⽰的数列:1、1、2、3、5、8、13、21.....按照其递推公式写出的递归函数如下:public static int fib(int n) throws Exception {if (n < 0)throw new Exception("参数不能为负!");else if (n == 0 || n == 1)return n;elsereturn fib(n - 1) + fib(n - 2);}递归调⽤的过程像树⼀样,通过观察会发现有很多重复的调⽤。

递归的总结

递归的总结

递归的总结什么是递归递归是一种解决问题的方法,它在函数的定义中调用函数自身。

通过将问题分解为更小的子问题并解决它们,递归可以解决复杂的问题。

递归在许多算法和数据结构中都有广泛的应用,特别是在树和图的操作中。

递归的基本原理递归的基本原理是将问题分解为更小的子问题并解决它们,直到达到最小的基本问题,然后将结果合并起来得到最终解决方案。

递归函数通常包括两个部分:基本情况和递归情况。

基本情况是指递归函数的退出条件,当满足某个条件时,递归停止。

递归情况是指递归函数调用自身解决子问题。

递归的优点使用递归可以简化代码的实现,将复杂的问题分解为更小的问题,使得代码更易于理解和维护。

递归还能够处理一些特殊的问题,例如树和图的遍历、排列组合等。

在这些情况下,递归是最自然的解决方法。

递归的缺点递归可能导致栈溢出,特别是在处理大规模问题时。

每次递归函数调用都会在调用栈中占用一些内存,当递归层级过深时,会超过系统栈的容量。

递归的效率通常比迭代低,尤其是对于一些简单的问题,使用递归可能会导致不必要的计算。

递归的应用场景递归广泛应用于许多算法和数据结构中。

以下是一些常见的应用场景:1.树的遍历:递归可以方便地实现树的深度优先遍历和广度优先遍历。

2.排列组合:递归可以生成所有可能的排列组合,例如生成一个数组的所有子集、一个字符串的所有排列等。

3.动态规划:递归可以将一个复杂的问题分解为更小的子问题,并使用动态规划技术进行优化。

4.回溯算法:递归可以方便地实现回溯算法,用于解决一些搜索问题,例如八皇后问题、求解数独等。

注意事项在使用递归时,需要注意以下几点:1.确定递归的退出条件,避免出现死循环。

2.确保每次递归调用都在向退出条件逼近,否则可能会导致递归层级过深。

3.尽量避免不必要的递归调用,以提高代码的效率。

4.在处理大规模问题时,考虑使用迭代或其他更高效的解决方法,避免栈溢出的风险。

总结递归是一种强大的问题解决方法,它通过将问题分解为更小的子问题来解决复杂的问题。

C语言的递归函数详解

C语言的递归函数详解

C语⾔的递归函数详解⽬录函数递归什么是递归?递归的俩个必要条件代码引例1栈溢出(StackOverflow)合理使⽤递归代码引例3代码引例4解释要合理使⽤递归总结函数递归程序调⽤⾃⾝的编程技巧称为递归 recursion)函数⾃⼰调⽤⾃⼰就是递归你也可以理解成是⼀种嵌套结构,但递归分为俩部分,第⼀是“递”,进⼊嵌套结构。

第⼆是”归“,最终会⼀步⼀步返回。

第⼀次接触递归都会很懵,慢慢理解这个过程就明⽩了。

什么是递归?递归做为⼀种算法在程序设计语⾔中⼴泛应⽤。

⼀个过程或函数在其定义或说明中有直接或间接调⽤⾃⾝的⼀种⽅法,它通常把⼀个⼤型复杂的问题层层转化为⼀个与原问题相似的规模较⼩的问题来求解,递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算,⼤⼤地减少了程序的代码量。

递归的主要思考⽅式在于:把⼤事化⼩递归的俩个必要条件代码引例1接受⼀个整型值(⽆符号),按照顺序打印它的每⼀位。

例如:输⼊:123,输出 1 2 3参考代码:#include <stdio.h>void print(int n) {if(n>9){print(n/10);}printf("%d ", n%10);}int main(){int num = 123;print(num);return 0; }运⾏结果如下:我们要怎么理解这个函数递归的实现呢我们可以采⽤画图⽅式理解这个过程所以我们可以看到,递归必须满⾜俩个必要条件:1.存在限制条件,当满⾜这个限制条件的时候,递归便不再继续。

2.每次递归调⽤之后越来越接近这个限制条件。

题中的限制条件就是(n>9),当我们的n通过(n/10)越来越少,直⾄n=1,⽆法满⾜时,递归停⽌,并开始返回。

这⾥有⼀个重要点就是print(n/10),如果没有这个条件,换成print(n)的话,n⼀直⽆法减⼩,⼀直进⾏递归。

最后会导致栈溢出(Stack Overflow)。

递归函数的定义

递归函数的定义

递归函数的定义递归函数作为计算机编程中的一种重要方式,经常被使用来解决需要重复操作的问题,特别是与树形数据结构、图形结构等有关的问题。

那么,什么是递归函数?怎样定义递归函数呢?本文将围绕这些问题来展开详细的介绍。

一、递归函数的概念递归函数,也叫递归算法,在计算机编程中是一种经常被使用的方法,它可以在代码中反复调用自己来解决重复的问题。

递归函数与迭代函数不同,它不需要使用循环结构来解决问题,而是使用函数的调用关系来实现重复执行。

递归函数通常需要满足以下两个条件:其一,存在一种基本情况,即函数的某些状态可以不需要递归地就能得到结果;其二,每次递归时,状态都向着基本情况点移动,这种状态可以使用函数的参数来进行改变。

二、递归函数的定义过程定义递归函数需要考虑以下几步:1.设计问题求解的思路和逻辑:递归函数解题的核心在于如何将任务分解到越来越小的任务,一直分解到最基本任务进行解决。

需要明确的是,递归调用的任务必须是与原始问题有着相同解决思路的不同规模的子问题。

在设计问题求解的思路和逻辑时,需要对问题进行分析和抽象,确定问题的核心点和子问题之间的关系。

2.编写递归函数头部:递归函数头部包含函数名和参数。

在设计递归函数时,需要考虑函数的参数如何传递,如何进行变化,以及递归函数是否需要返回结果。

在头部中应该尽可能描述清楚这些信息。

需要注意的是,递归函数的头部一般需要有一些条件来控制递归的深度,否则可能会陷入死循环。

3.编写递归终止条件:由于递归函数的特性,如果没有终止条件,函数将会无限地调用自己,从而导致栈溢出等程序错误。

因此,为了保证递归函数的正确执行,必须确定递归的终止条件。

终止条件是函数处理任务的最小情况,当程序执行到这一点时,递归调用将会停止并返回值。

4.编写递归子问题的处理:这一步是递归算法的核心部分,需要设计实现递归过程中子问题的处理方法。

具体来说,需要明确递归与子问题的关系,子问题如何获取、如何传递及在递归过程中如何处理等。

深入理解递归函数

深入理解递归函数

深入理解递归函数刚开始接触编程对递归调用都是比较头痛,很多年前我也会一样。

昨天晚上睡觉突然想起了谭浩强C语言的汉诺塔递归调用,记得当时是在高中的时候,我表姐在上大学,她把谭浩强的C语言给了我,只看书不实践,现在想起来效果还真差。

其中递归调用汉诺塔看了好久都没有整明白,直到上大学学习C语言也还没有搞明白,当学到递归调用了,我就去问老师,老是说回去看看,下周告诉我。

谁知到老师真的很忙,下周也没有结果。

后来自己什么时候明白的也忘记了。

刚开始接触递归都会告诉你,递归占用资源,使程序复杂,最好不要使用;还有人说,如果这个人一来就是用递归,我肯定不会聘用他。

但是我认为这些观点太片面。

递归算法的目的降低程序的复杂度,解放大脑负担,让大脑更加专注于问题本身。

程序的性能跟递归没有什么关系,更重要的时算法本身,我们会在稍后讲解一下同一种算法同样是递归,性能的差异巨大。

设计模式中,很多模式都存在递归。

刚开始接触递归的,往往都会在里面打圈圈,自己越绕越晕,觉得递归太复杂。

其实看待递归的时候,也是要分层面看待,不要把自己的大脑当做是电脑,可以绕很多的圈圈,有人说人的大脑同时能处理7个左右的变量,绕一圈就多几个变量,能绕几圈啊。

呵呵。

找到一个算法,在编写算法的时候,只考虑一次递归所做的事情,如果遇到到递归调用函数的时候,把他当做一个函数整体考虑,他能完成他要完成的事情,要相信他,也要相信自己。

我们所在的层面就是算法的层面,或者一次执行的层面。

如果在算法层面和递归调用层面来回穿插的思考,读懂递归算法将非常困难,递归的复杂度就在于压栈会导致大量的变量需要存储,对我们的大脑来说负担太重,但是对计算机来说是小意思,相对来说算法层面往往很简单,所以我们一定要站在算法层面考虑问题,而不是递归层面。

下面来看我如何一步一步实现汉诺塔:(VS 2010 C# 控制台程序)[csharp]view plaincopyprint?1.class Program2.{3.static void Main(string[] args)4. {5.6.7. }8.9.static void Move(int n, char a, char b, char c)10. {11.if (n < 1) return;12.if (n == 1)13. {14. MoveTo(a, c);15. }16.else17. {18.19.//以下三句可能存在问题,只是为了快速思考,先写上,看着代码找感觉。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

深入理解递归函数
刚开始接触编程对递归调用都是比较头痛,很多年前我也会一样。

昨天晩上睡觉突然想起了谭浩强C语言的汉诺塔递归调用,记得当吋是在高中的时候,我表姐在上大学,她把谭浩强的C语言给了我,只看书不实践,现在想起来效果还真差。

其中递归调用汉诺塔看了好久都没有整明白,直到上大学学习C语言也还没有搞明白,当学到递归调用了,我就去问老师,老是说回去看看,下周告诉我。

谁知到老师真的很忙,下周也没有结果。

后来自己什么吋候明白的也忘记了。

刚开始接触递归都会告诉你,递归占用资源,使程序复杂,最好不要使用;还有人说,如果这个人一来就是用递归,我肯定不会聘用他。

但是我认为这些观点太片面。

递归算法的目的降低程序的复杂度,解放大脑负担,让大脑更加专注于问题本身。

程序的性能跟递归没有什么关系,更重要的时算法本身,我们会在稍后讲解一下同i种算法同样是递归,性能的差异巨大。

设计模式中,很多模式都存在递归。

刚开始接触递归的,往往都会在里面打圈圈,自己越绕越晕,觉得递归太复杂。

其实看待递归的时候,也是要分层面看待,不要把自己的大脑当做是电脑,可以绕很多的圈圈,有人说人的大脑同时能处理7个左右的变量,绕一圈就多几个变量,能绕几圈啊。

呵呵。

找到一个算法,在编写算法的吋候,只考虑一次递归所做的事情,如果遇到到递归调用函数的时候,把他当做一个函数整体考虑,他能完成他要完成的事情,要相信他,也要相信自己。

我们所在的层面就是算法的层面,或者一次执行的层面。

如果在算法层面和递归调用层面来回穿插的思考,读懂递归算法将非常困难,递归的复杂度就在于压栈会导致大量的变量需要存储,对我们的大脑来说负担太重,但是对汁算机来说是小意思,相对来说算法层面往往很简单,所以我们一定要站在算法层面考虑问题,而不是递归层面。

下面来看我如何一步一步实现汉诺塔:(VS2010C#控制台程序)
[csharp] view plaincopyprint^C
1.class Program
2・{
3・static void Main(string[] args)
4.<
6.
7.
8.
9.static void Move(int n» char a, char b, char c)
10.{
11.if (n < 1) return;
12.if (n == 1)
13・{
14.MoveTo(a, c);
15.}
16.else
17.{
18 •
19. 〃以下三句可能存在问题,只是为了快速思考,先写上,看着代码找感觉。

20•Move(n - a,b, c);
21.MoveTo(a^ c);
22.Move(n - 1, a, b, c);
23・}
24.}
25.
25.private static void MoveTo(char a, char c)
26.{
27.throw new NotlmplementedException();
28.}
29.}
凭着感觉直接写了个Move方法,第一个参数为盘子的个数,将所有盘子从a移动到c°
第一个判断,防止错误的参数。

第二个判断,当n等于1时,也就是一个盘子,直接盘子从a移动到c上。

如果多余一个,将个盘子从a移到b,再将最下面一个从a移动到c,最后从b上将n-1个盘子移动到c上。

[csharp] view plaincopyprint^C
h・〃这三句肯定有问题的,只是为了快速把人脑里的想法写出看,看着来找感觉。

2.Move(n・1, a, b, c); //这句要实现将A座n・l的盘子移动到B上。

3.MoveTo(a, c); //这句实现将A座最下血的一个盘子移动到C上
4.Move(n・1, a, b, c); //这句要实现将移动到B座的盘子在移动到C座上,这就OK 了。

因为Move这个方法就是要把盘子从a移动到c,所以我们在递归调用时仅仅记住这个函数的这个功能就行了,这是一个函数的整体功能。

我们分别来讲解当N>1的3个步骤:
第一步,讲个盘子从a移动到b。

把盘子全部移动到b位置和c的方法是一样的,也就是算法是一样的。

只是规模比原来少1。

所以我们可以递归调用Move方法来解决将个盘子从a移动到bo 这吋b就像相当于原来的c位置了,那么就这样调用Move(n-1, a, c, b).
第二步,当个盘子从a移动到b Z后,a上就一个盘子,我们就可以直接将盘子移动到c上面。

调用MoveTo(a, c)实现盘子的移动。

在这一步,其实就是相当于移动只有一个盘子的情况,我们还可以递归调算法本身Move(1,a, b, c);这样调用也是可以的。

在执行完成后,a位置上是空的,b位置上有个盘子,c位置上有一个最大的盘子。

第三步,在第二步之后,我们只需要将b位置上的盘子都移动到c位置就可以了。

这个和第一步类似,只是位置变了。

b相当于原来的a位置(因为盘子在b上),a位置相当于原来的b位置,因为移动到c ,所以c还是相当于与原来的c位置。

语句调用这样写Move(n ・ 1, b, a, c);
完善MoveTo力法,输出结果就好了。

如果是图形移动,在这里写移动图形的方法即可。

[csharp] view plaincopyprint?C
1. private static void MoveTo(char from, char to)
2・{
3. Console.WriteLine(from + " -> " + to);
4. }
在Main 函数中写代码测试一下:
[csharp] view plaincopyprint?C
11. Move(3, 'A', 'B 1, '「);
2 • Console•ReadKey();
运行一下没有问题。

将代码进行重构和调整:
1. class Program
2・{
3・ static void Main(string[] args)
4. {
5. Hanor(4, ”A“, “B“, “C“);
6 • Console•ReadKey();
7・ }
8.
9. static void Hanor(int n, string platOne, string platTwo
》 string platThre
if (n < 1) return;
if (n == 1)
{
MoveTo(platOne J platThree);
}
else
{
Hanon(n - 1, platone, platThree^ platTwo);
MoveTo(platOne J platThree); 10-
11.
12. 13. 14 • 15. 16. 17. 18 [csharp] view plaincopyprint
} private static void MoveTo(string a, string c) { Console.WriteLine(a + "・> ” + c); }
函数执行对不对,最好不要用大脑去测试,用电那运行测试,看看运行结果正常就OK
To 如果好奇,感兴趣,或者测试一下大脑,可以自己绕一绕。

卜•面在举一个递归算法的例子,用于说明他递归算法的性能,代码如下:
[csharp] view plaincopyprint^C
1. static int Fun(int n)
2・{
3.
if(n <= 1)
4.
{ 5.
return 1; 6・
} 7.
return Fun(n - 1) + Fun(n - 1); 8. } 这个函数的表示:当nv=1吋,f(n) =1;当n>1时,f(n) = f(n ・1) + f(n ・1)
这个函数这样写性能会随n 的增大成指数下降,汉诺塔的性能和这个是一样的。

这都是 算法导致的,对于这个问题,他会调用2的(n-1)次方次,但是改变一下解决问题的算法, 那么情况会是怎样? f(n-1)+f(n-1)其实相当于f(n-1)*20如果算法改成这样,结果不会有 任何问题,性能却非常高,函数被调用次数变为n 次。

所以算法才是对新能影响的关键。

修改该后的代码如下:
[csharp] view plaincopyprint
1. static int Fun(int n)
21.
22.
23-
24 •
25.
26.
27.
|
28. }
3. if (n <= 1)
4・{
5・return 1;
6・}
7.return Fun(n - 1) * 2;
,8. }
在这里有一点要注意,可能有些人担心前后两个f(n-1)的结果可能不一样,其实这种担心是因为递归的原因。

之前说了,在递归调用时要把函数作为整体来看待,当做一般的函数来看待。

所以这里的结果肯定会是一样的。

对于汉诺塔能不能也能不性能提升到这么高呢?这也在于算法,能不能提高性能在于能不能找到算法。

相关文档
最新文档