递归法求解迷宫问题
2010-06-11 15:42
260 查看
求迷宫中从入口到出口的所有路径是一个经典的问题,这里所使用的方法是递归法,什么是递归呢?函数中有调用自己的函数,我们称为递归函数。一个问题可以分解为一个与自身求解过程相同的小问题,我们都可以用递归,比如,Hanoi塔问题,八皇后问题。我们知道用递归方法求解问题时最关键的就是递归函数的设计,在设计递归函数时应该注意以下几点:
1.严格定义函数的功能和接口,对函数中所得的和原问题性质相同的子问题,只要接口一致,便可进行递归调用;
2.对函数中每个递归调用都看成是一个简单的语句,切忌想得太深。
其实,在使用递归的时候我们可以想一下归纳法的思想,如果n成立,我们即可使用n的结论来计算n+1,在计算n+1时无需想着n+1之前的n是如何计算的,因为我们已经假设n已经成立了,无需在怀疑它的正确性。
下面给出使用递归法求解迷宫问题的源代码,代码中求出了共有多少条道路可以通。
/*
* 求迷宫中有多少条可通路径,1表示城墙,0表示道路
*/
#include <stdio.h>
#include <stdlib.h>
struct point{
int p[10][10];
int mark[10][10];
};
struct point pt;
int c = 0;
void build_maze(void)
{
FILE *fd;
char c;
int i = 0,j;
fd = fopen("maze.txt","r"); //maze.txt中画有迷宫地图
while(!feof(fd)){
c = fgetc(fd);
if(isdigit(c)){
pt.p[i/10][i%10] = c - 48;
pt.mark[i/10][i%10] = 0;
i++;
}
}
fclose(fd);
return;
}
int maze(int x,int y)
{
/*
*当进入函数时,已经处在迷宫的(x,y)坐标位置;
*现在从(x,y)相邻的四个方向前进,前进条件是,该方向能通(值为0),并且还没有走过(0表示没走过);
*当(x,y) == (8,8)终点时,表示求得一条可通路径
*/
int i,j;
if (x == 8 && y == 8) { //OUT
c++;
return 1;
}
if (x - 1 >= 0 ) { //东方
if (pt.p[x - 1][y] == 0) {
if (pt.mark[x - 1][y] == 0) {
pt.mark[x - 1][y] = 1;
maze(x - 1,y);
pt.mark[x - 1][y] = 0; //退回,将走过的标记清除
}
}
}
if (y + 1 <= 9){
if (pt.p[x][y + 1] == 0 ){
if (pt.mark[x][y + 1] == 0) {
pt.mark[x][y + 1] = 1;
maze(x,y + 1);
pt.mark[x][y + 1] = 0;
}
}
}
if (x + 1 <= 9){
if (pt.p[x+1][y] == 0){
if (pt.mark[x + 1][y] == 0) {
pt.mark[x + 1][y] = 1;
maze(x + 1,y);
pt.mark[x + 1][y] = 0;
}
}
}
if (y - 1 >= 0){
if (pt.p[x][y - 1] == 0){
if(pt.mark[x][y - 1] == 0) {
pt.mark[x][y - 1] = 1;
maze(x,y - 1);
pt.mark[x][y - 1] = 0;
}
}
}
return 0;
}
/* Find a way to go out of the maze */
int main()
{
int i,j;
build_maze();
pt.mark[1][1] = 1;
maze(1,1);
if(c > 0) {
printf("There are %d ways for us to go out!/n",c);
}
else
printf("Can't go out!/n");
/* 打印迷宫地图 */
for(i = 0;i<10;i++){
for(j = 0;j < 10;j++){
printf("%d",pt.p[i][j]);
}
printf("/n");
}
return 0;
}
1.严格定义函数的功能和接口,对函数中所得的和原问题性质相同的子问题,只要接口一致,便可进行递归调用;
2.对函数中每个递归调用都看成是一个简单的语句,切忌想得太深。
其实,在使用递归的时候我们可以想一下归纳法的思想,如果n成立,我们即可使用n的结论来计算n+1,在计算n+1时无需想着n+1之前的n是如何计算的,因为我们已经假设n已经成立了,无需在怀疑它的正确性。
下面给出使用递归法求解迷宫问题的源代码,代码中求出了共有多少条道路可以通。
/*
* 求迷宫中有多少条可通路径,1表示城墙,0表示道路
*/
#include <stdio.h>
#include <stdlib.h>
struct point{
int p[10][10];
int mark[10][10];
};
struct point pt;
int c = 0;
void build_maze(void)
{
FILE *fd;
char c;
int i = 0,j;
fd = fopen("maze.txt","r"); //maze.txt中画有迷宫地图
while(!feof(fd)){
c = fgetc(fd);
if(isdigit(c)){
pt.p[i/10][i%10] = c - 48;
pt.mark[i/10][i%10] = 0;
i++;
}
}
fclose(fd);
return;
}
int maze(int x,int y)
{
/*
*当进入函数时,已经处在迷宫的(x,y)坐标位置;
*现在从(x,y)相邻的四个方向前进,前进条件是,该方向能通(值为0),并且还没有走过(0表示没走过);
*当(x,y) == (8,8)终点时,表示求得一条可通路径
*/
int i,j;
if (x == 8 && y == 8) { //OUT
c++;
return 1;
}
if (x - 1 >= 0 ) { //东方
if (pt.p[x - 1][y] == 0) {
if (pt.mark[x - 1][y] == 0) {
pt.mark[x - 1][y] = 1;
maze(x - 1,y);
pt.mark[x - 1][y] = 0; //退回,将走过的标记清除
}
}
}
if (y + 1 <= 9){
if (pt.p[x][y + 1] == 0 ){
if (pt.mark[x][y + 1] == 0) {
pt.mark[x][y + 1] = 1;
maze(x,y + 1);
pt.mark[x][y + 1] = 0;
}
}
}
if (x + 1 <= 9){
if (pt.p[x+1][y] == 0){
if (pt.mark[x + 1][y] == 0) {
pt.mark[x + 1][y] = 1;
maze(x + 1,y);
pt.mark[x + 1][y] = 0;
}
}
}
if (y - 1 >= 0){
if (pt.p[x][y - 1] == 0){
if(pt.mark[x][y - 1] == 0) {
pt.mark[x][y - 1] = 1;
maze(x,y - 1);
pt.mark[x][y - 1] = 0;
}
}
}
return 0;
}
/* Find a way to go out of the maze */
int main()
{
int i,j;
build_maze();
pt.mark[1][1] = 1;
maze(1,1);
if(c > 0) {
printf("There are %d ways for us to go out!/n",c);
}
else
printf("Can't go out!/n");
/* 打印迷宫地图 */
for(i = 0;i<10;i++){
for(j = 0;j < 10;j++){
printf("%d",pt.p[i][j]);
}
printf("/n");
}
return 0;
}
相关文章推荐
- Java算法---华为oj迷宫问题求解(广度优先搜索)
- 基于栈操作的迷宫问题求解
- 栈求解迷宫问题
- “八皇后”问题递归法求解
- 应用栈求解迷宫问题(C++实现)
- 走迷宫问题:回溯法和递归法
- 迷宫问题的C语言求解
- 第十二周项目5 迷宫问题之图的深度优先遍历算法求解
- [置顶] 模拟求解迷宫问题(DFS+BFS)
- 栈的思想用于求解迷宫问题
- 经典算法<一>迷宫问题 1.单条路径 DFS求解 C++实现
- 求解迷宫问题
- 回溯法求解迷宫问题
- 栈求解迷宫问题
- 迷宫问题的C语言求解
- 栈的应用——迷宫求解问题
- 用递归法:设计算法求解汉诺塔问题,并编程实现。 (1) Hanoi(汉诺)塔问题分析 这是一个古典的数学问题,是一个用递归方法解题的典型例子。问题是这样的:古代有一个梵塔,塔内有3个座 A,B,C
- C语言及程序设计进阶例程-6 递归法问题求解
- 【数据结构】用回溯法求解迷宫问题
- 用栈和递归求解迷宫问题