函数讲解(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
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;
}

代码讲解:

函数讲解(4)之函数的递归与迭代_第1张图片

 

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

      Print(1234)

             |  |

Print(123)           4

Print(12)       3    4

Printf(1)    2  3    4

    1          2   3    4

函数讲解(4)之函数的递归与迭代_第2张图片

 

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

 下图是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;
}

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

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

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

你可能感兴趣的:(C语言知识点,c语言)