编程学习笔记8--递归的运用
2014-12-11 20:57
162 查看
递归的定义
在一个子程序(过程或函数)的定义中又直接或间接地调用该子程序本身,称为递归。递归是一种非常有用的程序设计方法。
递归调用的一般格式为:
if (边界条件1)
赋予边界值1
else if (边界条件2)
赋予边界值2
……
else
调用解决问题的通式
递归解决问题的关键:1.找出递推公式2.找到递归终止条件
注意事项:由于函数的局部变量是存在栈上的,如果有体积大的局部变量,比如数组,而递归层次又可能很深的情况下,也许会导致栈溢出,因此可以考虑使用全局数组或动态分配数组
先遍历后操作
下面这些是我自己不会的,感谢提供代码的人,给我参考!
解法老鼠的走法有上、左、下、右四个方向,在每前进一格之后就选一个方向前进,无法前进时退回选择下一个可前进方向,如此在阵列中依序测试四个方向,直到走到出口为止,这是递回的基本题,请直接看程式应就可以理解。
关于棋盘的问题,都可以用递回求解,然而如何减少递回的次数?在八个皇后的问题中,不必要所有的格子都检查过,例如若某列检查过,该该列的其它格子就不用再检查了,这个方法称为分支修剪。
在一个子程序(过程或函数)的定义中又直接或间接地调用该子程序本身,称为递归。递归是一种非常有用的程序设计方法。
递归调用的一般格式为:
if (边界条件1)
赋予边界值1
else if (边界条件2)
赋予边界值2
……
else
调用解决问题的通式
递归解决问题的关键:1.找出递推公式2.找到递归终止条件
注意事项:由于函数的局部变量是存在栈上的,如果有体积大的局部变量,比如数组,而递归层次又可能很深的情况下,也许会导致栈溢出,因此可以考虑使用全局数组或动态分配数组
递归的形式
先操作后遍历void Func(char ch) { if(ch<=‘z’) { cout<<ch; Func(ch+1); } }
先遍历后操作
void Func(char ch) { if(ch<=‘z’) { Func(ch+1); cout<<ch;} }
下面这些是我自己不会的,感谢提供代码的人,给我参考!
汉诺塔
河内之塔(Towers of Hanoi)是法国人M.Claus(Lucas)于1883年从泰国带至法国的,河内为越战时北越的首都,即现在的胡志明市; 1883年法国数学家 Edouard Lucas曾提及这个故事,据说创世纪时Benares有一座波罗教塔,是由三支钻石棒(Pag)所支撑,开始时神在第一根棒上放置64个由上至下依由小至大排列的金盘(Disc),并命令僧侣将所有的金盘从第一根石棒移至第三根石棒,且搬运过程中遵守大盘子在小盘子之下的原则,若每日仅搬一个盘子,则当盘子全数搬运完毕之时,此塔将毁损,而也就是世界末日来临之时。#include <stdio.h> void hanoi(int n, char A, char B, char C) { if(n == 1) { printf("Move sheet %d from %c to %c\n", n, A, C);/**一个的时候直接放置*/ } else { hanoi(n-1, A, C, B);/**移动第n个盘子的前提是先想办法把前面的n-1个盘子从A挪到B上,以C为辅助*/ printf("Move sheet %d from %c to %c\n", n, A, C);/**完成后再把第n个从A移动到C上*/ hanoi(n-1, B, A, C);/**最后把前n-1个盘子从B以A为辅助挪动到C上。 } } int main() { int n; printf("请输入盘数:"); scanf("%d", &n); hanoi(n, 'A', 'B', 'C'); return 0; }
老鼠走迷官
老鼠走迷宫是递回求解的基本题型,我们在二维阵列中使用2表示迷宫墙壁,使用1来表示老鼠的行走路径,试以程式求出由入口至出口的路径。解法老鼠的走法有上、左、下、右四个方向,在每前进一格之后就选一个方向前进,无法前进时退回选择下一个可前进方向,如此在阵列中依序测试四个方向,直到走到出口为止,这是递回的基本题,请直接看程式应就可以理解。
#include <stdio.h> #include <stdlib.h> int visit(int, int); int maze[7][7] = { {2, 2, 2, 2, 2, 2, 2}, {2, 0, 0, 0, 0, 0, 2}, {2, 0, 2, 0, 2, 0, 2}, {2, 0, 0, 2, 0, 2, 2}, {2, 2, 0, 2, 0, 2, 2}, {2, 0, 0, 0, 0, 0, 2}, {2, 2, 2, 2, 2, 2, 2} }; int startI = 1, startJ = 1; // 入口 int endI = 5, endJ = 5; // 出口 int success = 0; int main(void) { int i, j; printf("显示迷宫:\n"); for(i = 0; i < 7; i++) { for(j = 0; j < 7; j++) { if(maze[i][j] == 2) printf("█"); else printf(" "); } printf("\n"); } if(visit(startI, startJ) == 0) { printf("\n没有找到出口!\n"); } else { printf("\n显示路径:\n"); for(i = 0; i < 7; i++) { for(j = 0; j < 7; j++) { if(maze[i][j] == 2) printf("█"); else if(maze[i][j] == 1) printf("◇"); else printf(" "); } printf("\n"); } } return 0; } int visit(int i, int j) { maze[i][j] = 1; if(i == endI && j == endJ) success = 1; if(success != 1 && maze[i][j+1] == 0) visit(i, j+1); if(success != 1 && maze[i+1][j] == 0) visit(i+1, j); if(success != 1 && maze[i][j-1] == 0) visit(i, j-1); if(success != 1 && maze[i-1][j] == 0) visit(i-1, j); if(success != 1) maze[i][j] = 0; return success; }
八皇后
西洋棋中的皇后可以直线前进,吃掉遇到的所有棋子,如果棋盘上有八个皇后,则这八个皇后如何相安无事的放置在棋盘上,1970年与1971年, E.W.Dijkstra与N.Wirth曾经用这个问题来讲解程式设计之技巧。关于棋盘的问题,都可以用递回求解,然而如何减少递回的次数?在八个皇后的问题中,不必要所有的格子都检查过,例如若某列检查过,该该列的其它格子就不用再检查了,这个方法称为分支修剪。
#include <stdio.h> #include <stdlib.h> #define N 8 int column[N+1]; // 同栏是否有皇后,1表示有 int rup[2*N+1]; // 右上至左下是否有皇后 int lup[2*N+1]; // 左上至右下是否有皇后 int queen[N+1] = {0}; int num; // 解答编号 void backtrack(int); // 递回求解 int main(void) { int i; num = 0; for(i = 1; i <= N; i++) column[i] = 1; for(i = 1; i <= 2*N; i++) rup[i] = lup[i] = 1; backtrack(1); return 0; } void showAnswer() { int x, y; printf("\n解答 %d\n", ++num); for(y = 1; y <= N; y++) { for(x = 1; x <= N; x++) { if(queen[y] == x) { printf(" Q"); } else { printf(" ."); } } printf("\n"); } } void backtrack(int i) { int j; if(i > N) { showAnswer(); } else { for(j = 1; j <= N; j++) { if(column[j] == 1 &&rup[i+j] == 1 && lup[i-j+N] == 1) { queen[i] = j;// 设定为占用 column[j] = rup[i+j] = lup[i-j+N] = 0; backtrack(i+1); column[j] = rup[i+j] = lup[i-j+N] = 1; } } } }
相关文章推荐
- 运用递归 取某个目录下的所有子目录及文件
- 第十二周oj项目A运用递归倒序输出数字
- 运用递归给定一个int型的整数,倒序输出他的每一位上的数字
- Mysql中的递归层次查询(根据父节点查找所有的子节点和根据子节点查询所有的父节点)的两种运用
- 汇编语言--运用迭代和递归的方式按照要求输出
- 编程学习笔记5--递推的运用
- JS实现函数递归、运用技巧
- 运用递归调用方法来反转字符串
- 练习 4-12 运用 printd 函数的设计思想编写一个递归版本的 itoa 函数,即通过递归 调用把整数转换为字符串
- 【递归】递归的运用
- python递归、迭代器和生成器在算法中的运用
- 第十二周项目3-5:运用递归进行二进制转换
- 递归的运用
- 递归运用--蟠桃记
- MFC 运用CFileFind 类 递归实现文件夹的 复制 (MFC 文件操作 二)
- 运用递归 删除父节点同事删除子节点
- 递归:运用递归思想解题
- 二叉查找树的各项操作(重点是结点的删除部分和递归的运用)
- 递归的运用
- javascript实现二叉树的创建,遍历,添加,查找最大值最小值和指定值的寻找及删除功能——递归的多次运用