本文来自B站郝斌老师的《数据结构》整理的来,若有侵权,欢迎私信我。
课程来源:https://www.bilibili.com/video/av6159200?p=59
递归定义:一个函数自己直接或间接调用自己递归满足三个条件
- 递归必须得有一个明确的中止条件
- 该函数所处理的数据规模必须在递减
- 这个转化必须是可解的
循环和递归
- 递归
- 易于理解
- 速度慢
- 存储空间大
- 循环
- 不易理解
- 速度快
- 存储空间小
函数的调用:
- 当在一个函数的运行期间调用另一个函数时,在运行被调函数之前,系统需要完成三件事:
- 将所有的实际参数、返回地址等信息传递给被调函数保存。
- 为被调函数的局部变量(也包括行参)分配存储空间。
- 将控制转移到被调函数的入口。
- 从被调函数返回函数之前,系统也要完成三件事:
- 保存被调函数的返回结果。
- 释放被调函数所占的存储空间。
- 依照被调函数保存的返回地址将控制转移到调用函数。
- 当有多个函数相互调用时,按照”后调用先返回“的原则,上述函数之间信息传递和控制转移必须借助”栈“来实现,即系统将整个程序运行时所需的数据空间安排在一个栈中,每当调用一个函数时,就在栈顶分配一个存储区,进行压栈操作,每当一个函数退出时,就释放它的存储区,就做出栈操作,当前运行的函数永远都在栈顶位置。
- A函数调用A函数和A函数调用B函数在计算机看来是没有任何区别的,只不过用我们日常的思维方式理解比较怪异而已!
-
1+2+3+…+100的和
# include <stdio.h> int sum(int); int main(void) { int n = 100; printf("%d\n",sum(n)); return 0; } int sum(int n) { if(1 == n) return 1; else return n + sum(n-1); }
-
求阶乘
# include <stdio.h> long multi(int); int main(void) { printf("%ld\n",multi(6)); return 0; } long multi(int n) { if (1 == n) return 1; else return n * multi(n - 1); }
-
汉诺塔
使用递归的思想,将n个盘子上边的n-1个先进行移动,知道n-1为1,此时直接移动,以此完成汉诺塔问题。
void hanoi(int n,char a,char b,char c)
{
如果只有一个盘子:
直接将盘子从A柱子移到C柱子
否则:
先将A柱子上的n-1个盘子借助C柱子移到B柱子
再直接将盘子从A柱子移到C柱子
最后再将B柱子上的盘子借助A柱子移到C柱子上
}
代码实现样例:
# include <stdio.h> void hanoi(int, char, char, char); int main(void) { //柱子编号 char ch1 = 'A'; char ch2 = 'B'; char ch3 = 'C'; //盘子数量 int n; printf("请输入盘子的数量"); scanf_s("%d", &n); hanoi(n, 'A', 'B', 'C'); return 0; } void hanoi(int n, char A, char B, char C) { if (1 == n) printf("编号为%d的盘子:%c-->%c\n", n, A, C); else { hanoi(n - 1, A, C, B); printf("编号为%d的盘子:%c-->%c\n", n, A, C); hanoi(n - 1, B, A, C); } }
-
走迷宫
A*(A-Star)算法实现
递归的应用
- 树和森林就是以递归的方式定义的
- 树和图的很多算法
- 很多数学公式:例如斐波拉契数列(1,2,3,5,8,13,21,34)