回溯算法
回溯算法是递归算法的特殊形式,其基本的思想是首先一条路走到底,能走则走,不能走则退回到上一个结点,选择另一个方向尝试;
回溯算法求解迷宫
可将迷宫问题分成两个结构体,一个结构体将迷宫作为整体,存放迷宫的路口个数,路口集合以及迷宫的出口,另一个结构体用于存放每个路口的方向;
(一)结构体定义
#include <stdio.h>
#include <stdlib.h>
typedef struct
{
int left; //向左
int forward; //向前
int right; //向右
}InterSection;
typedef struct
{
int mazeSize; //路口个数
InterSection *intSec; //路口集合
int Exit; //出口
}Maze;
(二)设计回溯搜索算法
int TravMaze(Maze *m,int currSetValue)
//currSetValue表示当前所处的路口
{
//currSetValue>0表示有路径存在,可以继续探索发现一条路径
if(currSetValue>0)
{
if(currSetValue==m->Exit) //递归出口
{
printf("%d <==",currSetValue); //输出出口
return 1;
}
//向左探索
else if(TravMaze(m,m->intSec[currSetValue].left)==1)
{
printf("%d <==",currSetValue);
return 1;
}
//向前探索
else if(TravMaze(m,m->intSec[currSetValue].forward)==1)
{
printf("%d <==",currSetValue);
return 1;
}
//向右探索
else if(TravMaze(m,m->intSec[currSetValue].right)==1)
{
printf("%d <==",currSetValue);
return 1;
}
}
return 0; //currSetValue=0表示无路径存在,返回0;
}
释:当一条路走到头发现走不通时返回0,这时选择代码向下运行,选择另一个方向,继续探索,直到返回1,此时最后的路就是迷宫的解;
(三)创建迷宫
void CreatMaze(char *filename,Maze *m)
{
//按文件Filename中存放的数据创建迷宫m
FILE *fp;
int i;
if((fp=fopen(filename,"r"))==NULL)
{
printf("数据文件无法打开");
return;
}
fscanf(fp,"%d",&m->mazeSize);
//建立mazaSize+1个元素的数组
m->intSec=(InterSection *)malloc(sizeof(InterSection)*(m->mazeSize+1));
for(i=1;i<=m->mazeSize;i++)
{
fscanf(fp,"%d%d%d",&m->intSec[i].left,&m->intSec[i].forward,&m->intSec[i].right); //读入所有路口结构体数据
}
fscanf(fp,"%d",&m->Exit); //读入出口数值
fclose(fp);
}
(四)主函数设计
void main()
{
Maze m; //定义一个迷宫结构体
int start=1;
CreatMaze("Maze1.dat",&m); //创建迷宫,将迷宫结构体的地址传给CreatMaze函数
if(TravMaze(&m,start))
{
printf("\n此迷宫的一条通路入上");
}
else printf("\n此迷宫");
system("pause");
}
运行过程
运行结果