递归算法在计算机中的状态变化

1、题目如下:

设有一个递归算法如下:
int X(int n){
	if(n<=3) 
		return 1;
	else
		return X(n-2)+X(n-4)+1;
}
则计算X(X(8))时需要计算X函数_____次

2、题目分析

首先这是一个递归算法,要计算X(X(8))执行X函数次数,必须从内到外;
先分析X(8)执行X函数的次数,进而得到X(8)的结果,再代入到外部X函数中继续进行计算。

  • 数学分析

1. 先计算X(8)的值:

X(8)… … … … … … … … … … … … … … … … 此行调用了X函数1
= X(6) + X(4) + 1 … … … … … … … … … … 此行调用了X函数2
= X(4) + X(2) + 1 + X(2) + X(0) + 1 + 1 … 此行调用了X函数4
= X(2) + X(0) + 1 + 1 +1 + 1 + 1 + 1 + 1… 此行调用了X函数2
= 1 + 1 + 1 + 1 +1 + 1 + 1 + 1 + 1
= 9
所以内层函数X(8)计算结果为9;共执行X函数9
进而X(X(8))就可以写成X(9),然后求其执行X函数的次数

2. 再计算X(9)的值:

X(9)… … … … … … … … … … … … … … … … 此行调用了X函数1
= X(7) + X(5) + 1 … … … … … … … … … … 此行调用了X函数2
= X(5) + X(3) + 1 + X(3) + X(1) + 1 + 1 … 此行调用了X函数4
= X(3) + X(1) + 1 + 1 +1 + 1 + 1 + 1 + 1… 此行调用了X函数2
= 1 + 1 + 1 + 1 +1 + 1 + 1 + 1 + 1
= 9
可以看到X(9)执行X函数的次数也是9次;

根据数学元素可以算出`X(X(8))`执行X函数的总次数为`18`次,函数返回结果为`9`;
所以可以得出答案,则计算`X(X(8))`时需要计算X函数`9`次。

3、计算机程序是如何执行的呢?

计算机程序执行的传参和计算状态

根据上图可以看到计算机在执行此程序是,函数调用(传参)和函数返回(计算)时候的状态,向下的箭头表示函数调用(传参)状态,向上的箭头表示函数返回(计算)状态,也可以清晰的看到调用次数。
实际上上图计算机程序执行就是一个完整的递归树

4、此函数调用过程

调用前,系统完成:

  1. 将实参,返回地址等传递给被调用函数
  2. 为被调用函数的局部变量分配存储区
  3. 将控制转移到被调用函数的入口

调用后,系统完成:

  1. 保存被调用函数的计算结果
  2. 释放被调用函数的数据区
  3. 依照被调用函数保存的返回地址将控制转移到调用函数

5、递归算法

递归算法(英语:recursion algorithm)在计算机科学中是指一种通过重复将问题分解为同类的子问题而解决问题的方法。递归式方法可以被用于解决很多的计算机科学问题,因此它是计算机科学中十分重要的一个概念。绝大多数编程语言支持函数的自调用,在这些语言中函数可以通过调用自身来进行递归。计算理论可以证明递归的作用可以完全取代循环,因此在很多函数编程语言(如Scheme)中习惯用递归来实现循环。

能够解决的问题:

  1. 数据的定义是按递归定义的。如Fibonacci函数。
  2. 问题解法按递归算法实现。如Hanoi问题。
  3. 数据的结构形式是按递归定义的。如二叉树、广义表等。

递归函数调用的实现

1、“层次”

主函数         0层
第1次调用      1层
第i次调用      i层

2、“递归工作栈”
3、“工作记录” :实在参数,局部变量和返回地址

效率分析

  1. 时间效率

与递归树的节点数成正比 :T(n) = O(2^n)

  1. 空间效率

与递归树的深度成正比 : S(n) = O(n)

递归的优缺点

  • 优点 :结构清晰,程序易读
  • 缺点 :每次调用要生成工作记录,保存状态信息,入栈;返回时要出栈,恢复状态信息,时间开销大

6、代码实现

  1. 程序实现过程
    下面的程序可以清楚地看到函数执行的次数和函数调用是传参的状态

main.c

#include<stdio.h>
int count = 0;
int X(int n){
	count = count + 1;
	printf("count = %d  n = %d\n", count, n);
	if (n<=3) {
		return 1;
	}
	else {
		return X(n-2)+X(n-4)+1;
	}
}

int main(){
	X(X(8));
	printf("执行X函数次数为%d",count);
	return 0;
}
  1. 程序运行结果
count = 1  n = 8
count = 2  n = 6
count = 3  n = 4
count = 4  n = 2
count = 5  n = 0
count = 6  n = 2
count = 7  n = 4
count = 8  n = 2
count = 9  n = 0
count = 10  n = 9
count = 11  n = 7
count = 12  n = 5
count = 13  n = 3
count = 14  n = 1
count = 15  n = 3
count = 16  n = 5
count = 17  n = 3
count = 18  n = 1
执行X函数次数为18
原创文章 10 获赞 21 访问量 1640

猜你喜欢

转载自blog.csdn.net/qq_44487263/article/details/105137281
今日推荐