函数讲解(4)之函数的递归与迭代

一.什么是递归?

         程序调用自身的编程技巧称为递归( recursion)。 递归做为一种算法在程序设计语言中广泛应用。 一个过程或函数在其定义或说明中有直接或间接 调用自身的 一种方法,它通常把一个大型复杂的问题层层转化为一个与原题相似的规模较小的问题来求解, 递归策略 只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量。 递归的主要思考方式在于:把大事化小。

        首先来看一组代码

int main() {
	printf("haha\n");
	main();
	return 0;
}

 代码讲解:首先在主函数中输入一行haha,之后调用主函数main(),进入后又打印一行haha,接下来又会调用main()函数,再进行打印.....这就是递归,但不是真正意义上的递归,这种的递归没有满足两个必要条件,会造成死递归,最终导致栈溢出(Stack overflow )的错误。(注:栈溢出就是栈区的内存满了,已经再也放不下东西了)

2 递归的两个必要条件

     a. 存在限制条件,当满足这个限制条件的时候,递归便不再继续。

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

举个相应的例子

//1.实现:输入一个无符号整形数字,输出输入数的每一位
//例:输入1234,    输出:1 2 3 4

# include<stdio.h>
void Print(unsigned int n) {
	while (n>9) {
		Print(n / 10);
	}
	printf("%zu\n", n % 10);
}

int main() {
	unsigned int n = 0;
	scanf("%d", &n);
	Print(n);
	return 0;
}

代码讲解:

 

其实代码通过递归就可以分解为

      Print(1234)

             |  |

Print(123)           4

Print(12)       3    4

Printf(1)    2  3    4

    1          2   3    4

 

上图为递归关系图。画的不好看,还请海涵 !

 下图是N的阶乘使用递归思路完成,设计思路与上面那个代码差不多,就不再一 一讲解了。

此外大家还可以了解了解汉诺塔问题和青蛙跳台阶问题,这两类都是递归思路实现。

//求N的阶乘--递归实现
int my_jie(int n){
	if (n <= 1) 
		return 1;
		if (n >= 2) 
			return n*my_jie(n - 1);
		
	}
int main() {
	int n = 0;
	scanf("%d", &n);
	int ret = my_jie(n);
	printf("%d\n", ret);
	return 0;
}

二.函数的迭代

        迭代换个词讲也可以称为循环,迭代是函数内某段代码实现循环,而迭代与普通循环的区别是:循环代码中参与运算的变量同时是保存结果的变量,当前保存的结果作为下一次循环计算的初始值。

        函数的实现方式其实就分为递归实现和迭代(循环)实现,两者各有各的好处,但也有相应的缺点。

1.递归的能力在于用有限的语句来定义对象的无限集合。

2.迭代:利用变量的原值推算出变量的一个新值.如果递归是自己调用自己的话,迭代就是A不停的调用B。

3、递归中一定有迭代,但是迭代中不一定有递归,大部分可以相互转换.能用迭代的不用递归,递归调用函数,浪费空间,并且递归太深容易造成堆栈的溢出。

来看一道例题,求第n个斐波那契额数。

斐波那契数列为:1,1,2,3,5,8,13,21,34,55......

每一个数都是由它的前两个数相加而成,其中规定了第一二个数字为1

//递归实现斐波那契
int Fib(int n) {
	if (n <= 2) {
		return 1;
	}
	else{
		return Fib(n - 1) + Fib(n - 2);
	}
}
int main() {
	int n = 0;
	scanf("%d", &n);
	int ret = Fib(n);
	printf("%d\n", ret);
	return 0;
}

       递归实现斐波那契数列时,若输入过大的数,比如求第40个及以上斐波那契数时,会有时间上的浪费,空间效率虽然上去了,但时间效率太过低下。


//求第n个斐波那契数---迭代----时间效率高
int Fib(int n) {
	int a = 1;
	int b = 1;
	int c = 0;
	while (n >= 3) {
		 c = a + b;
		a = b;
		b = c;
		n--;
	}
	return c;
}
int main() {
	int n = 0;
	scanf("%d", &n);
	int ret = Fib(n);
	printf("%d\n", ret);
	return 0;
}

 而迭代法的运算却是相当块,一输入就立马出结果。

所以在编写函数的时候,要选择性的定义函数功能实现,两种情况都考虑考虑再进行编写。

 希望上述所讲对大家理解函数能有所帮助!

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 函数嵌套调用函数递归是两种不同的编程技巧。 函数嵌套调用指的是一个函数在内部调用另一个函数。这种方式常常用于将复杂的任务分解成若干个较简单的子任务。这种方式的优点是代码可读性和可维护性较好,缺点是不容易解决递归类型的问题。 函数递归则是一种函数自己调用自己的方法。递归的实现需要确定递归的终止条件,以避免函数无限递归递归常常用于解决数学归纳类型的问题,例如斐波那契数列求值、求解树形结构等。这种方式的优点是可以解决一些复杂的问题,缺点是代码实现难度较大,对于循环深度过大的递归调用可能会导致程序崩溃。 ### 回答2: 函数的嵌套调用函数递归是编程中常用的两种方法,它们的主要区别在于函数调用方式和逻辑控制。 首先,函数的嵌套调用是指在一个函数的定义中调用其他函数。当一个函数内部调用另一个函数时,程序会先执行被调用函数,然后回到原函数继续执行。这种调用方式可以在编写复杂的程序时提高代码的可读性和模块化程度,因为每个函数完成一个特定的功能。 其次,函数递归是指一个函数在其函数体内直接或间接调用自身。递归函数通过将问题划分为规模更小的子问题并在子问题上调用自身来解决问题。递归函数需要一个终止条件,当满足终止条件时,递归函数会不断返回结果,从而逐步解决原始问题。递归函数在解决特定问题时往往比较简洁和直观。 函数的嵌套调用函数递归的主要区别在于函数调用方式和逻辑结构。嵌套调用是线性的,函数按照调用的顺序执行,每次调用都会返回到上一级函数。而函数递归是通过函数自身的调用迭代解决问题,它的执行过程是直接或间接调用自身,直到满足终止条件。 根据实际情况,我们可以选择使用函数的嵌套调用函数递归来解决问题。函数的嵌套调用适用于有明确调用顺序的场景,而函数递归适用于需要通过递归调用解决的问题。同时,递归函数使用不当可能导致栈溢出等错误,需要谨慎使用和设置终止条件。 ### 回答3: 函数的嵌套调用是指在一个函数内部调用另一个函数。在嵌套调用中,当函数A中调用函数B时,函数B执行完毕后会返回到函数A中继续执行。这种调用方式可以让程序具有更高的灵活性和模块化,可以使得程序的结构更加清晰。 而函数递归是指在一个函数内部调用自身。在递归调用中,当函数执行到递归调用语句时,会暂时跳出当前函数,执行调用函数,直到达到递归的终止条件后才开始逐层返回。递归调用可以解决一些需要重复执行相同或相似操作的问题,可以让程序更加简洁,但也容易导致性能问题和栈溢出等错误。 区别可以从以下几个方面来看: 1. 调用对象不同:嵌套调用调用其他函数,而递归调用调用自身。 2. 调用时机不同:嵌套调用可以在任何需要的时候进行调用,而递归调用需要满足递归的终止条件才会返回。 3. 执行方式不同:嵌套调用函数调用完毕后会直接返回到调用位置继续执行后续代码,而递归调用递归终止条件满足后才会开始逐层返回,并依次执行每一层递归调用之后的代码。 4. 难易程度不同:嵌套调用相对比较简单,适用于一些简单的函数调用场景;而递归调用相对较复杂,需要在编写代码时设计好递归终止条件和递归调用的逻辑,适用于解决一些重复性问题的场景。 综上所述,函数的嵌套调用函数递归是两种不同的调用方式,各自适用于不同的场景,开发者可以根据实际需求选择合适的调用方式。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

橙予清的zzz~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值