<C语言>递归思维及其实现-----汉诺塔问题
2017-08-17 11:08
525 查看
<<<<<<<递归思维及其实现>>>>>>>>>>
作者:wsg
时间:2017年8月17日
1、概念:
·一个过程或一个函数,在其定义或者说明中有直接或间接地调用自身的一种思想方法。
2、递归条件:
·子问题和原始问题是相同的事情;
·不能无限制地调用,必须有个出口(边界条件)。
3、如何设计递归算法:
·确定递归公式;
·确定边界条件。
4、递归一般用来解决:
·数据的递归定义;
·递归算法的实现;
·数据结构形式按递归定义(比如二叉树)。
5、递归算法相对于常用的算法(如for循环),运行效率低。若操作不当,很容易造成栈溢出等错误。所以在设计算法的时候,尽量避免使用递归。除非没有更好的算法,或者只能使用递归的时候才使用。
6、经典实例:汉诺塔问题。(后面例3有代码)
7、注意:
·一定要有一个边界条件;
·不要在递归函数里面申请大块内存(malloc)
递归模板:
递归:
1.确定参数
2.确定参数的函数
3.确定简单情况下的函数
4.确定复杂情况下的函数
==============================
模板:
int f(参数)
{
if (简单情况条件)
return 简单情况下函数
else
return 复杂情况下函数
}
汉诺塔:
参数n:盘子个数
设f(n):n个盘子总共需要移动的步数
简单情况下的函数
f(n) = 1 n = 1;
复杂情况下的函数
f(n) = 2f(n-1)+1; //(n > 1)
===============================
例1:输出1-100
<
4000
br />
例2:输入一个整数,求1^2+2^2+3^2+……+n^2
例:3:<汉诺塔>有三根柱子A、B、C,有n个大小不一的圆盘,原始状态,所有圆盘都在A柱上(上面圆盘必须必下面圆盘小),现在要求,将所有圆盘移动到C上,一次只能移动一个,并且必须放在某一根之子上。找出移动次数最小的方案。
例3:
作者:wsg
时间:2017年8月17日
1、概念:
·一个过程或一个函数,在其定义或者说明中有直接或间接地调用自身的一种思想方法。
2、递归条件:
·子问题和原始问题是相同的事情;
·不能无限制地调用,必须有个出口(边界条件)。
3、如何设计递归算法:
·确定递归公式;
·确定边界条件。
4、递归一般用来解决:
·数据的递归定义;
·递归算法的实现;
·数据结构形式按递归定义(比如二叉树)。
5、递归算法相对于常用的算法(如for循环),运行效率低。若操作不当,很容易造成栈溢出等错误。所以在设计算法的时候,尽量避免使用递归。除非没有更好的算法,或者只能使用递归的时候才使用。
6、经典实例:汉诺塔问题。(后面例3有代码)
7、注意:
·一定要有一个边界条件;
·不要在递归函数里面申请大块内存(malloc)
递归模板:
递归:
1.确定参数
2.确定参数的函数
3.确定简单情况下的函数
4.确定复杂情况下的函数
==============================
模板:
int f(参数)
{
if (简单情况条件)
return 简单情况下函数
else
return 复杂情况下函数
}
汉诺塔:
参数n:盘子个数
设f(n):n个盘子总共需要移动的步数
简单情况下的函数
f(n) = 1 n = 1;
复杂情况下的函数
f(n) = 2f(n-1)+1; //(n > 1)
===============================
例1:输出1-100
/******** ===使用for循环做简单很多=== #include <stdio.h> int main(void) { int i; for(i=1; i<=100; i++) { printf("%d\n", i); } return 0; } *********/ //使用递归算法 #include <stdio.h> void func(int n); int main(void) { int a = 100; func(a); } void func(int n) { if(n>1) //递归的边界条件 { func(n-1); //函数调用自身,递归 } printf("%d\n", n); } /***可以这样来理解: void func(int n) { if(n>1) { if((n-1)>1) //递归的边界条件 { func((n-1)-1); //一层一层进去,再从最里面出来,故打印出来的结果就是1-100 } printf("%d\n", n); } printf("%d\n", n); } *****/
<
4000
br />
例2:输入一个整数,求1^2+2^2+3^2+……+n^2
#include <stdio.h> int recursion(int n); //声明 int main(void) { int a, sum; printf("请输入一个整数:\n"); scanf("%d", &a); sum = recursion(a); printf("结果为:%d\n", sum); } int recursion(int n) //递归函数的定义 { if(n>1) { return n*n+recursion(n-1); //recursion(n-1)将一层一层递归执行return n*n+recursion(n-1)下去,直到n>1不成立。 } }
例:3:<汉诺塔>有三根柱子A、B、C,有n个大小不一的圆盘,原始状态,所有圆盘都在A柱上(上面圆盘必须必下面圆盘小),现在要求,将所有圆盘移动到C上,一次只能移动一个,并且必须放在某一根之子上。找出移动次数最小的方案。
#include <stdio.h> void func(int n, char from, char buf, char to); int main(void) { int n; char col[3] = {'A','B','C'};//定义三根柱子 printf("请输入圆盘个数:\n"); scanf("%d", &n); //输入有多少个盘 printf("最简移动方案:\n"); func(n,'A', 'B', 'C'); return 0; } //用n个盘,原始盘全在from上,要移动到to上,中间工具用buf作过渡 void func(int n, char from, char buf, char to) { if(n == 1) { printf("%c--->%c\n", from, to); } else { func(n-1, from, to, buf); //A--->B柱 printf("%c--->%c\n", from, to); func(n-1, buf, from, to); //B--->C柱 } }
例3:
相关文章推荐
- 约瑟夫循环c语言实现 (<<数据结构与算法>>-王曙燕 约瑟夫环问题解答)
- 【经典问题】汉诺塔(递归、C语言实现)
- C语言实现Hanoi(汉诺塔)问题的递归求解
- <二叉树 前中后 层序 非递归遍历 c语言实现>
- C语言 N阶汉诺塔问题的递归实现
- <C语言>用递归调用函数解决穷举n位二进制数问题
- <数据结构学习与实验指导>3-1一元多项式求导/3-2汉诺塔的非递归实现
- 数据结构基础(6)--递归和函数调用--汉诺塔问题C语言实现
- STL学习笔记:用非递归的方法实现汉诺塔问题
- 解决 ”不允许在查询中显式构造实体类型“问题及使用其他方法实现返回 List<Model对象>或者IQueryable<Model对象>对象
- <4>c语言实现ATM存取款系统(链表)
- 用<hr/>实现横线竖线的简便问题
- 汉诺塔问题的递归实现(扩展)
- 数字问题之斐波那契数列全解<Java实现>
- 用<hr/>实现横线竖线的简便问题
- 各种排序算法及其java程序实现 <转>
- <有道笔试题>链表加法的递归实现
- List<> 转换为Dataset的C#代码实现 解决Nullable问题
- 链表问题之无头单链表删节点<Java实现>
- 红黑树<C语言实现>