用递归函数求解迷宫问题(C语言代码)

合集下载

用C语言解决迷宫问题

用C语言解决迷宫问题

⽤C语⾔解决迷宫问题#include <stdio.h>#include <stdlib.h>#define ROW 10#define COL 10/*迷宫中位置信息*/typedef struct position{int x;int y;}position;/*在迷宫中的当前位置的信息,也是⼊栈的基本元素*/typedef struct SElem{int di;position seat;}SElem;/*链式栈中节点的定义*/typedef struct position_stack{SElem p;struct position_stack *next;}*Stack_pNode,Stack_Node;void InitStack(Stack_pNode *Link){*Link = NULL;}void push(Stack_pNode *Link,SElem e){Stack_pNode new_SElem = (Stack_pNode)calloc(1,sizeof(Stack_Node));new_SElem->p = e;new_SElem->next = NULL;if (*Link == NULL)*Link = new_SElem;else{new_SElem->next = *Link;*Link = new_SElem;}}int pop(Stack_pNode *Link,SElem *e){if (*Link == NULL)return 0;*e = (*Link)->p;Stack_pNode q = *Link;*Link = (*Link)->next;free(q);return 1;}int top(Stack_pNode Link, SElem *e){if (Link == NULL)return 0;*e = Link->p;return 1;}int empty(Stack_pNode Link){if (Link == NULL)return 1;elsereturn 0;}int reverse(Stack_pNode *Link){Stack_pNode p, q, r;if (*Link == NULL || (*Link)->next == NULL)return 0;r = *Link;p = (*Link)->next;q = NULL;while (p){r->next = q;q = r;r = p;p = p->next;}r->next = q;*Link = r;}void print(Stack_pNode Link){Stack_pNode r = Link;while (r){printf("(%d,%d) -> ",r->p.seat.x,r->p.seat.y);r = r->next;}printf("exit\n");}int curstep = 1;/*纪录当前的⾜迹,填写在探索前进的每⼀步正确的路上*//*迷宫地图。

C语言递归实现迷宫寻路问题

C语言递归实现迷宫寻路问题

C语⾔递归实现迷宫寻路问题迷宫问题采⽤递归和⾮递归两种⽅法,暂时完成递归⽅法,后续会补上⾮递归⽅法#include<stdio.h>#include<stdbool.h>bool findPath(int a[][8],int i,int j){//递归找出⼝if(i==6&&j==6)//如果找到了⽬标a[6][6]则返回truereturn true;if(a[i][j]==0)//若当前路径未被找到,则继续{a[i][j]=2;//当前⾛的路径置为2,表⽰⾛过if(findPath(a,i+1,j)||findPath(a,i,j+1)||findPath(a,i-1, j)||findPath(a,i-1,j))//每个⽅向都判断,依次展开递归,寻找最佳路径return true;//若选择的路径可以⾛,则返回trueelse{//若当前选择的路径不能⾛a[i][j]=0;//弹栈并恢复路径,回退到上⼀次的位置return false;}}else//未能找到最终点return false;}void print(int a[][8])//打印当前的⼆维数组表{for(int i=0;i<8;i++){for(int j=0;j<8;j++){printf("%d ",a[i][j]);}printf("\n");}}int main(){int a[8][8]={0};for(int i=0;i<8;i++)//设置围墙和障碍物{a[0][i]=1;a[i][0]=1;a[7][i]=1;a[i][7]=1;}a[3][1]=1;a[3][2]=1;print(a);printf("-----------after find path-----------\n");findPath(a, 1, 1);print(a);}。

C语言实验:迷宫问题(搜索,C语言实现栈、队列)

C语言实验:迷宫问题(搜索,C语言实现栈、队列)

C语⾔实验:迷宫问题(搜索,C语⾔实现栈、队列)Description给定迷宫起点和终点,寻找⼀条从起点到终点的路径。

(0,1)(2,0)起点(1,1)(1,2)(1,3)(1,4)(2,0)(2,1)(2,4)(3,0)(3,1)(3,2)终点(3,4)(4,1)上图中黄⾊代表墙,⽩⾊代表通路,起点为(1,1),终点为(3,4)。

要求搜寻策略是从起点开始按照“上、下、左、右”四个⽅向寻找终点,到下⼀个点继续按照“上、下、左、右”四个⽅⾯寻找,当该结点四个⽅向都搜寻完,但还没到终点时,退回到上⼀个点,直到找到终点或者没有路径。

⽐如上图从(1,1)开始,向上(0,1)不通,向下到(2,1);到了(2,1)后继续按“上、下、左、右”四个⽅⾯寻找,上已经⾛过,向下到(3,1);到(3,1)后上已经⾛过,下和左不通,向右到(3,2);到(3,2)四个⽅⾯都不通,回到(3,1)四个⽅向都不通,再回到(2,1),(1,1);到达(1,1)后下已经⾛过,左不通,继续向右⾛,重复这个过程最后到达(3,4)。

Input第⼀⾏两个数m和n表⽰迷宫的⾏数和列数。

迷宫⼤⼩不超过100×100第⼆⾏四个数x1,y1,x2,y2分别表⽰起点和终点的坐标。

接下来是m⾏n列的数,⽤来表⽰迷宫,1表⽰墙,0表⽰通路。

Output从起点到终点所经过的路径的坐标。

如果不存在这样的路径则输出“No Path!”。

Sample Input5 61 1 3 41 1 1 1 1 11 0 0 0 0 11 0 1 1 0 11 0 0 1 0 11 1 1 1 1 1Sample Output(1 1)(1 2)(1 3)(1 4)(2 4)(3 4)1.思路:(1)若当前点是终点,dfs函数返回1;(2)若不是终点,将此点标记为1,对该点4个⽅向进⾏搜索,实现⽅式为定义int dir[4][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} }; 通过⼀个⼩循环: for(int i = 0; i < 4; i++) {  position nextp; nextp.x = dir[i][0] + now.x;nextp.y = dir[i][1] + now.y;...... } 进⾏搜索;若该点的下⼀个点nextp不是墙,未⾛,并且没有超界则将nextp压⼊栈中,递归调⽤dfs,若此过程经过(1)判断返回了1,说明最终找到了通往终点的路,便可以返回1,结束函数,此时栈中已储存了通往终点的路径,若没有通路,则弹出栈顶元素,根据递归原理该路径上的所有点都会弹出并标记未⾛,回溯到之前的点,继续向其他⽅向搜索,直到找到终点或遍历完整个图。

用递归函数求解迷宫问题(C语言代码)

用递归函数求解迷宫问题(C语言代码)

用递归函数求解迷宫问题(C语言代码)// algo3-9.cpp 用递归函数求解迷宫问题(求出所有解)#include // 根据《PASCAL程序设计》(郑启华编著)中的程序改编struct PosType // 迷宫坐标位置类型{int x; // 行值int y; // 列值};#define MAXLENGTH 25 // 设迷宫的最大行列为25typedef int MazeType[MAXLENGTH][MAXLENGTH]; // [行][列] // 全局变量PosType end; // 迷宫终点位置MazeType m; // 迷宫数组int x,y; // 迷宫行数,列数// 定义墙元素值为0,可通过路径为-1,通过路径为足迹void Print(int x,int y){ // 输出解int i,j;for(i=0;i<x;i++)< p="">{for(j=0;j<y;j++)< p="">printf("%3d",m[i][j]);printf("\n");}printf("\n");}void Try(PosType cur,int curstep){ // 由当前位置cur、当前步骤curstep试探下一点int i;PosType next; // 下一个位置PosType direc[4]={{0,1},{1,0},{0,-1},{-1,0}}; // {行增量,列增量} // 移动方向,依次为东南西北for(i=0;i<=3;i++) // 依次试探东南西北四个方向{next.x=cur.x+direc[i].x; //下一点的行坐标next.y=cur.y+direc[i].y; //下一点的列坐标if(m[next.x][next.y]==-1) // 是通路{m[next.x][next.y]=++curstep;if(next.x!=end.x||next.y!=end.y) // 没到终点Try(next,curstep); // 试探下一点(递归调用)elsePrint(x,y); // 输出结果m[next.x][next.y]=-1; // 恢复为通路,试探下一条路 curstep--;}}}int main(){PosType begin;int i,j,x1,y1;printf("请输入迷宫的行数,列数(包括外墙):");scanf("%d,%d",&x,&y);for(i=0;i<="">{m[0][i]=0; // 行周边m[x-1][i]=0;}for(j=1;j<y-1;j++)< p="">{m[j][0]=0; // 列周边m[j][y-1]=0;}for(i=1;i<x-1;i++)< p="">for(j=1;j<y-1;j++)< p="">m[i][j]=-1; // 定义通道初值为-1printf("请输入迷宫内墙单元数:");scanf("%d",&j);if(j)printf("请依次输入迷宫内墙每个单元的行数,列数:\n"); for(i=1;i<=j;i++){scanf("%d,%d",&x1,&y1);m[x1][y1]=0;}printf("迷宫结构如下:\n");Print(x,y);printf("请输入起点的行数,列数:");scanf("%d,%d",&begin.x,&begin.y); printf("请输入终点的行数,列数:");scanf("%d,%d",&end.x,&end.y);m[begin.x][begin.y]=1;Try(begin,1); // 由第一步起点试探起 }</y-1;j++)<></x-1;i++)<></y-1;j++)<></y;j++)<></x;i++)<>。

迷宫(direction)C语言代码

迷宫(direction)C语言代码
/* 其中 1<=x1,x2<=M-2 , 1<=y1,y2<=N-2 */
voidmazePath(intmaze[][N],intdirection[][2],intx1,inty1,intx2,inty2) {
inti, j, k, g, h;
PSeqStackst;
DataTypeelement;
1,1,1,1,1,1,1,1,1,1,1
};
mazePath(maze,direction,1,1,6,9);
getchar();
return 0;
}
#include<stdio.h>
#include<conio.h>
intmigong[10][10]= //设置迷宫,最外围1为墙 里边0为可走路径 1为障碍
find=1;
}
if(find==1){ //判断是否找得到
lj[top].d=d;
top++;
lj[top].x=x;
lj[top].y=y;
d=-1;find=0; //重新调整方向
migong[x][y]=-1;}
else{
migong[lj[top].x][lj[top].y]=0;
top--;d=lj[top].d; //找不到的话退栈
case1:x=lj[top].x; y=lj[top].y+1;break;//方向为右
case2:x=lj[top].x+1; y=lj[top].y; break;//方向为下
case3:x=lj[top].x; y=lj[top].y-1;}//方向为左
if(migong[x][y]==0)

c语言迷宫问题代码实现

c语言迷宫问题代码实现
}SEAT;
structStackList
{
SEAT stack[MAXSIZE];
inttop;
}*Stack;
intEmptyStack(StackList*Stack)//判断是否为空栈
{
if(Stack->top==0)
return 0;
else
return 1;
}
intMove[4][2]={{0,1},{1,0},{0,-1},{-1,0}};//分别表示向东、西、南、北需要加上的坐标
CurSeat=temp;
find =1;
}
}
}
}
}while(EmptyStack(Stack));
return false;
}
voidPrintStack(StackList*Stack)//输出路线
{
if(Stack->top==0)
printf("There is no route can be out of the maze\n");
Mark(CurSeat);
if(CurSeat.x==end.x+1&&CurSeat.y==end.y+1)//如果找到出口,返回
{
return true;
}
else
{
intfind=0;
while(CurSeat.di<3&&find==0)//找下一个结点的方向
{
CurSeat.di++;
SEAT temp;
scanf("%d",&n);
printf("Please enter the labyrinth of the coordinates of the wall unit(0<=row,column):\n");

用c语言实现迷宫求解完美源代码

用c语言实现迷宫求解完美源代码

优先队列:用于存储待扩展节点,按照 f(n)值从小到大排序
A*搜索算法的C语言实现
算法流程:包括初始化、搜索、更新父节点等步骤 数据结构:使用优先队列来存储待搜索节点和已访问节点 实现细节:包括如何计算启发式函数、如何选择下一个节点等 性能优化:可以采用多线程、缓存等技术来提高算法的效率
A*搜索算法在迷宫求解中的应用
C语言实现A*搜 索算法
A*搜索算法的基本原理
定义:A*搜索算法是一种启发式搜索 算法,结合了最佳优先搜索和Dijkstra 算法的优点
基本思想:使用启发函数来评估节点的 重要性,优先选择最有希望的节点进行 扩展,从而有效地缩小搜索范围
关键参数:g(n):从起点经过节点n的 实际代价;h(n):从n到目标的估计代 价(启发式函数);f(n)=g(n)+h(n)
最短路径搜索
优化技巧:为了 提高搜索效率和 精度,可以采用 一些优化技巧, 如限制搜索范围、 使用优先队列等
C语言实现 Dijkstra算法
Dijkstra算法的基本原理
Dijkstra算法是一种用于求解最短路径问题的贪心算法 该算法通过不断选择当前最短路径的节点来逼近最短路径 Dijkstra算法适用于带权重的图,其中权重表示节点之间的距离 Dijkstra算法的时间复杂度为O((V+E)logV),其中V是节点数,E是边数
算法复杂度分析:时间复杂 度和空间复杂度分析
感谢您的观看
汇报人:XX
迷宫求解算法的C语言实现流程
初始化迷宫和路径
定义四个方向的移动方向
遍历迷宫,找到起点和终点
使用深度优先搜索或广度优先 搜索算法求解路径
C语言实现深度 优先搜索算法
深度优先搜索算法的基本原理

数据结构之迷宫问题求解(一)利用栈与递归求解出口

数据结构之迷宫问题求解(一)利用栈与递归求解出口

数据结构之迷宫问题求解(⼀)利⽤栈与递归求解出⼝ 本⽂适合于对迷宫问题已有初步研究,或阅读代码能⼒较强的⼈. 因此,如果你对迷宫问题⼀⽆所知,请参考其他更详细的资料. 迷宫问题,是⼀个对栈(Stack)典型应⽤的例⼦之⼀. 假如,有如下10X10的迷宫(0代表通路,1代表障碍),我们需要⽤写程序来找出迷宫的出⼝.1 1 1 1 1 1 1 1 1 11 1 1 0 1 1 1 0 1 10 0 0 0 1 0 0 0 1 11 1 0 1 1 0 1 0 0 11 1 0 1 0 0 1 0 1 11 1 0 1 1 1 1 0 0 11 1 0 0 0 0 0 0 1 11 1 0 1 0 1 1 0 1 11 1 0 1 0 1 1 0 1 11 1 1 1 1 1 1 0 1 1那么,我们可以通过两种⽅式完成.⽅式⼀:通过利⽤栈FILO(First In Last Out)的特性核⼼代码/**函数说明:通过栈来进⾏迷宫求解*参数说明:* Maze:迷宫地图数组* sz:迷宫⼤⼩* entry:迷宫⼊⼝点* path:⽤于寻找迷宫出⼝的栈*返回值:找到出⼝返回true,没找到返回false.*/bool FindMazePath(int *Maze,size_t sz,Pos &entry,stack<Pos>& path){//将⼊⼝压栈path.push(entry);//如果栈不为空while(!path.empty()){//获取栈顶元素,即上⼀次⾛的路径Pos cur = path.top();//将其标记为已⾛过Maze[cur.x*sz+cur.y] = 3;//找到出⼝if(sz-1==cur.x){return true;}Pos next = cur;//下⼀步,向右移动next.x += 1;if(CheckIsAccess(Maze,sz,next)){//可以向右移动,将当前步⼊栈path.push(next);continue;}next = cur;//下⼀步,向左移动next.x -= 1;if(CheckIsAccess(Maze,sz,next)){//可以向左移动,⼊栈path.push(next);continue;}//下⼀步,向上移动next = cur;next.y += 1;if(CheckIsAccess(Maze,sz,next)){//可以向上移动path.push(next);continue;}next = cur;//向下移动next.y -= 1;if(CheckIsAccess(Maze,sz,next)){//可以向下移动path.push(next);continue;}//上、下、左、右都不能⾛path.pop();}return false;}⽅式⼆:通过递归核⼼代码/**函数说明:根据递归寻找迷宫出⼝*参数说明* Maze:迷宫地图* sz:迷宫⼤⼩* entry:迷宫⼊⼝* path:⽤来判断是否存在出⼝的栈*返回值:⽆(如果存在出⼝,栈为空;如果不存在出⼝,栈中存在起点坐标)*/void FindMazePathR(int *Maze,size_t sz,Pos &entry,stack<Pos> & path){//将⼊⼝压栈path.push(entry);Pos cur = entry;//将已⾛过的路标记为3Maze[cur.x*sz+cur.y] = 3;//找到出⼝,直接返回if(sz-1==entry.x){//将起点坐标弹出path.pop();return ;}Pos next = cur;//右next.x += 1;if(CheckIsAccess(Maze,sz,next)){//以当前位置为起点,递归进⾏下⼀步FindMazePathR(Maze,sz,next,path);}next = cur;//左next.x -= 1;if(CheckIsAccess(Maze,sz,next)){FindMazePathR(Maze,sz,next,path);}//上next = cur;next.y += 1;if(CheckIsAccess(Maze,sz,next)){FindMazePathR(Maze,sz,next,path);}//下next = cur;next.y -= 1;if(CheckIsAccess(Maze,sz,next)){FindMazePathR(Maze,sz,next,path);}path.pop();}最后,附上整个程序的完整代码(代码量较少,声明与实现我就不分⽂件了)迷宫问题求解完整代码//相关函数的声明与实现#ifndef __MAZE_H__#define __MAZE_H__#include<iostream>#include<iomanip>#include<stack>#include<assert.h>namespace Maze{using namespace std;//迷宫⼤⼩static const int N = 10;//迷宫地图⽂件名static const char *const FILENAME = "MazeMap.txt";//坐标struct Pos{int x; //横坐标(本质是数组arr[i][j]的j)int y; //纵坐标(本质是数组arr[i][j]的i)};/*函数说明:从⽂件中获取迷宫地图参数说明:Maze:迷宫地图数组sz:迷宫⼤⼩返回值:⽆*/void GetMaze(int *Maze,size_t sz){FILE *fp = fopen(FILENAME,"r");//打开失败if(NULL==fp){//输出错误信息perror(FILENAME);//结束程序exit(1);}//将⽂件中的迷宫地图读⼊Maze数组内for(size_t i=0; i<sz; ++i){for(size_t j=0; j<sz;){//从⽂件流中获取字符char tmp = getc(fp);//字符为0或为1时,导⼊数组if(tmp=='0'||tmp=='1'){Maze[i*sz+j]=tmp -'0';++j;}else if(EOF==tmp){//⽂件已读完,循环还未停⽌//说明此处⽂件中的迷宫地图存在问题assert(false);return ;}}}//关闭⽂件fclose(fp);}/*函数说明:打印迷宫参数说明:Maze:迷宫地图数组sz:迷宫⼤⼩返回值:⽆*/void PrintMaze(int *Maze,size_t sz){cout<<setw(2);for(size_t i=0; i<sz; ++i){for(size_t j=0; j<sz; ++j){cout<<Maze[i*sz+j]<<setw(2);}cout<<endl;}}/*函数说明:检测当前位置是否可以通过参数说明:Maze:迷宫地图数组sz:迷宫⼤⼩cur:当前所在位置返回值:可以通过返回true,不能通过返回false.*/bool CheckIsAccess(int *Maze,size_t sz,Pos cur){if(cur.x>=0 && cur.x<sz && //⾏坐标是否越界cur.y>=0 && cur.y<sz && //列坐标是否越界Maze[cur.x*sz+cur.y]==0 ){ //所在⾏列是否可以通过return true;}return false;}/*函数说明:通过栈来进⾏迷宫求解参数说明:Maze:迷宫地图数组sz:迷宫⼤⼩entry:迷宫⼊⼝点path:⽤于寻找迷宫出⼝的栈返回值:找到出⼝返回true,没找到返回false.*/bool FindMazePath(int *Maze,size_t sz,Pos &entry,stack<Pos>& path){ //将⼊⼝压栈path.push(entry);//如果栈不为空while(!path.empty()){//获取栈顶元素,即上⼀次⾛的路径Pos cur = path.top();//将其标记为已⾛过Maze[cur.x*sz+cur.y] = 3;//找到出⼝if(sz-1==cur.x){return true;}Pos next = cur;//下⼀步,向右移动next.x += 1;if(CheckIsAccess(Maze,sz,next)){//可以向右移动,将当前步⼊栈path.push(next);continue;}next = cur;//下⼀步,向左移动next.x -= 1;if(CheckIsAccess(Maze,sz,next)){//可以向左移动,⼊栈path.push(next);continue;}//下⼀步,向上移动next = cur;next.y += 1;if(CheckIsAccess(Maze,sz,next)){//可以向上移动path.push(next);continue;}next = cur;//向下移动next.y -= 1;if(CheckIsAccess(Maze,sz,next)){//可以向下移动path.push(next);continue;}//上、下、左、右都不能⾛path.pop();}return false;}/**函数说明:根据递归寻找迷宫出⼝*参数说明* Maze:迷宫地图* sz:迷宫⼤⼩* entry:迷宫⼊⼝* path:⽤来判断是否存在出⼝的栈*返回值:⽆(如果存在出⼝,栈为空;如果不存在出⼝,栈中存在起点坐标)*/void FindMazePathR(int *Maze,size_t sz,Pos &entry,stack<Pos> & path){ //将⼊⼝压栈path.push(entry);Pos cur = entry;//将已⾛过的路标记为3Maze[cur.x*sz+cur.y] = 3;//找到出⼝,直接返回if(sz-1==entry.x){//将起点坐标弹出path.pop();return ;}Pos next = cur;//右next.x += 1;if(CheckIsAccess(Maze,sz,next)){//以当前位置为起点,递归进⾏下⼀步FindMazePathR(Maze,sz,next,path);}next = cur;//左next.x -= 1;if(CheckIsAccess(Maze,sz,next)){FindMazePathR(Maze,sz,next,path);}//上next = cur;next.y += 1;if(CheckIsAccess(Maze,sz,next)){FindMazePathR(Maze,sz,next,path);}//下next = cur;next.y -= 1;if(CheckIsAccess(Maze,sz,next)){FindMazePathR(Maze,sz,next,path);}path.pop();}}#endif迷宫求解测试代码#include"Maze.h"using namespace Maze;void MazeTest(){int arr[N][N]; //迷宫地图Pos entry = {2,0}; //起点坐标stack<Pos> path; //栈GetMaze((int *)arr,N); //将⽂件中迷宫导⼊到arr数组中PrintMaze((int *)arr,N);//打印迷宫FindMazePath((int *)arr,N,entry,path);//找迷宫出⼝cout<<endl<<endl; //换⾏处理(使界⾯更整齐)PrintMaze((int *)arr,N);//打印⾛过的迷宫}int main(){MazeTest();return 0;}总结: 1.利⽤栈去寻找迷宫出⼝,栈内最终会保存从⼊⼝到出⼝的所有路径. 2.利⽤递归去寻找迷宫出⼝,传进去的栈仅仅只是⽤来判断迷宫是否有出⼝, 3.利⽤递归去寻找出⼝时,因为递归的特性,将会遍历完迷宫内的所有路径. 最后,还有⼀个问题:如果⼀个迷宫存在多条路径可以到达出⼝,那么如何得到迷宫到出⼝的最短路径 有机会的话,我将会在下篇⽂章讨论此事.。

c语言走迷宫代码

c语言走迷宫代码

c语言走迷宫代码以下是一个简单的 C 语言走迷宫代码示例,使用了递归算法: ```c#include <stdio.h>#include <stdlib.h>int main() {int size, row, col, choice, i, j;maze[0][0] = "*";maze[1][0] = "O";maze[0][1] = "O";maze[1][1] = "*";size = 2;row = 2;col = 2;while (1) {printf("Enter row: ");scanf("%d", &row);printf("Enter col: ");scanf("%d", &col);if (row < 0 || row > size || col < 0 || col > size) { printf("Invalid row or col. Try again.");}if (maze[row][col] != "*") {printf("Current cell is free. Try again. ");continue;}maze[row][col] = "X";printf("Enter a choice (1-6): ");scanf("%d", &choice);switch (choice) {case 1:row++;col = 0;break;case 2:row--;col = 0;break;case 3:col++;break;col--;break;case 5:row--;col = 1;break;case 6:row++;col = 1;break;default:printf("Invalid choice. Try again. ");continue;}}printf(" maze: ");for (i = 0; i < size * size; i++) { for (j = 0; j < size; j++) {if (maze[i][j] == "*")printf("*");elseprintf("%c", maze[i][j]);}printf("");}return 0;}```该程序首先初始化了一个 2x2 的迷宫,其中 `maze[0][0]` 和`maze[1][0]` 分别标记为 `"O"` 和 `"*"`,其他地方都为空。

C语言解决迷宫求解问题

C语言解决迷宫求解问题
0110000110100111001011000迷宫的路径为括号内的内容分别表示为行坐标列坐标数字化方向即方向方向111212221321422431532542550迷宫路径探索成功
迷宫求解
任务:
可以输入一个任意大小的迷宫数据,用非递归的方法求出一条走出迷宫的路
径,并将路径输出。
#include<iostream>
//获取栈顶元素
if(!(p.GetPop().x==q.GetPop().x&&p.GetPop().y==q.GetPop().y))
p.Push(Temp2);
//如果有新位置入栈,则把上一个探索的位置存入栈 p
for(loop=0;loop<4;loop++) //探索当前位置的 4 个相邻位置
//使栈顶元素出栈
T GetPop();
//取出栈顶元素
void Clear();
//把栈清空
bool empty();
//判断栈是否为空,如果为空则返回 1,否则返回 0
};
Stack::Stack()
//构造函数,置空栈
{
top=NULL;
}
Stack::~Stack()
//析构函数
{
}
void Stack::Push(T e)
//输出路径
{
cout<<"迷宫的路径为\n";
cout<<"括号内的内容分别表示为(行坐标,列坐标,数字化方向,方向)\n";
Stack t;
//定义一个栈,按从入口到出口存取路径
int a,b;
T data;

迷宫问题

迷宫问题

问题求解报告1.题目简述:迷宫问题迷宫问题就是在8行8列的迷宫中寻找一条或多条从进口到出口的路径,并显示迷宫于屏幕同时显示出路径。

试以程序求出由入口至出口的路径。

2.求解方法:递归法首先用二维数组表示迷宫的结构,用2表示迷宫墙壁,使用1来表示行走路径,用0表示进口和出口。

其中迷宫用随机函数产生,即调用随机函数产生二维数组,进而用二维数组表示迷宫的结构。

采用递归法:在任意一个位置都有上、左、下、右四个行进方向,在每前进一格之前就选一个方向前进,无法前进时退回选择下一个可前进方向,然后选择一个行进顺序:先向右,后向下,再向左,最后向上;如此在二维数组中依序测试四个方向。

因此可以用递归调用,设置一个访问函数f(int i, int j):现在我们行进到A(i,j)处,依次判断其是否可以向右,向下,向左,向上前进,如果可以向右就优先向右,递归调用该函数f(i,j+1),如果不可以向右就判断是否可以向下,如果可以就递归调用函数f(i+1,j),直至递归函数的参数为出口的坐标,否则结束此次递归,返回没有可行的路径。

同时f也要用来处理某格是否被访问过,若被访问救将该处的值改为1。

3.结合程序代码的分析:(1).随机产生密迷宫的函数程序代码:void Random(int mg[8][8]){int i,j,k;srand((unsigned int )time(NULL));for(i=1;i<7;i++)for(j=1;j<7;j++){k=rand()%3; //随机生成0、1、2三个数if(k)mg[i][j]=0;elseelsemg[i][j]=2;}}for(j=0;j<8;j++)mg[0][j]=mg[7][j]=2; /*设置迷宫外围"不可走",保证只有一个出口和入口*/for(i=0;i<8;i++)mg[i][0]=mg[i][7]=2; /*设置迷宫外围"不可走",保证只有一个出口和入口*/mg[1][0]=mg[6][7]=mg[1][1]=mg[6][6]=0; //将入口、出口设置为"0"即可通过;因为距入口或出口一步的路是必经之路,置于0;}(2).递归调用程序代码:void visit(int i, int j) { //访问各个格子,按优先顺序:先右,后下,再左,最后向上int m, n;maze[i][j] = 1;if(i == endI && j == endJ) {printf("\n显示路径:\n");for(m = 0; m < 8; m++) {for(n = 0; n < 8; n++)if(maze[m][n] == 2)printf("□");else if(maze[m][n] == 1)printf("◇");elseprintf(" ");printf("\n");}}if(maze[i][j+1] == 0) visit(i, j+1); //递归调用if(maze[i+1][j] == 0) visit(i+1, j);if(maze[i][j-1] == 0) visit(i, j-1);if(maze[i-1][j] == 0) visit(i-1, j);maze[i][j] = 0;}由于迷宫的设计,老鼠走迷宫的入口至出口路径可能不只一条,如何求出所有的路径呢?求所有路径看起来复杂但其实更简单,只要在老鼠走至出口时显示经过的路径,然后退回上一格重新选择下一个位置继续递回就可以了,比求出单一路径还简单,我们的程式只要作一点修改就可以了。

数据结构 迷宫问题(栈、C)分解

数据结构 迷宫问题(栈、C)分解

合肥学院计算机科学与技术系课程设计报告2012 ~2013 学年第二学期课程数据结构与算法课程设计名称迷宫问题(栈)学生姓名陈强学号**********指导教师李红专业班级计算机科学与技术11级2013年3 月题目:迷宫问题(栈):以一个m*n的长方阵表示迷宫,0和1分别表示迷宫中的通路和障碍。

设计一个程序,对任意设定的迷宫,求出一条从入口到出口的通路,或得出没有通路的结论。

要求:首先实现一个以链表作存储结构的栈类型,然后编写一个求解迷宫的非递归程序。

求得的通路以三元组(i,j,d)的形式输出,其中:(i,j)指示迷宫中的一个坐标,d表示走到下一坐标的方向。

一、问题分析和任务定义此程序可以用二维数组存储迷宫数据,设定入口点的下标为(1,1),出口点的下标为(m,n)。

为处理方便起见,在迷宫的四周加一圈障碍。

对于迷宫中任一位置,均可约定有东、南、西、北四个方向可通,并默认以东、南、西、北的顺序进行搜索路线。

将走过的路线放入链栈中,当走出迷宫时,栈中及走出迷宫的路线;当走不出时,栈为空。

实现本程序需要解决以下几个问题:1.如何通过二维数组建立并存储迷宫。

2.如何进行路径搜索。

3.按一个方向搜索不到出路时怎么办?4.将符合条件的路线存储。

5.搜索到出路时按顺序输出路线。

首先,可以用二维数组存储迷宫,0和1分别表示迷宫中的通路和障碍,为处理方便起见,建立迷宫时在迷宫四周加一圈障碍。

例如一个5*5的迷宫用二维数组可表示为:int maze[7][7]= {1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,0,1,1,0,0,0,0,0,1,1,0,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1,1};路径搜索时,需要知道出口和入口的坐标,本程序默认为(1,1)、(m,n)。

定义一个移动坐标(xc,yc),用以记录搜索路线时当前位置的坐标。

搜索时默认按照东、南、西、北的优先顺序进行查找,其中,向东搜索用“1”表示,向南、向西、向北分别用“2”、“3”、“4”表示,“0”表示方向未知。

迷宫非递归求解(c语言)源代码

迷宫非递归求解(c语言)源代码

迷宫非递归求解(c语言)源代码.txt51自信是永不枯竭的源泉,自信是奔腾不息的波涛,自信是急流奋进的渠道,自信是真正的成功之母。

#include <stdio.h>#include <stdlib.h>#define MaxSize 100#define StackIncrement 10struct Seat{ //定义坐标结构体int x;int y;};typedef struct { //定义入栈信息元素类型int ord;Seat seat;int di;}SElemType;struct Stack{ //定义栈元素类型SElemType *base;SElemType *top;int StackLength;};Stack S;bool Map[10][10]={{0},{0,1,1,0,1,1,1,0,1,0},{0,1,1,0,1,1,1,0,1,0},{0,1,1,1,1,0,0,1,1,0},{0,1,0,0,0,1,1,1,1,0},{0,1,1,1,0,1,1,1,1,0},{0,1,0,1,1,1,0,1,1,0},{0,1,0,0,0,1,0,0,1,0},{0,0,1,1,1,1,1,1,1,0},{0}};bool is_through[10][10]={0};bool InitStack(Stack &S){ //构建一个栈S.base=S.top=(SElemType*)malloc(MaxSize*sizeof(SElemType));if(!S.base)return false;S.StackLength=MaxSize;return true;}bool Push(Stack &S,SElemType e){ // 将信息e入栈if((S.top-S.base)/sizeof(SElemType)==S.StackLength){S.base=(SElemType*)realloc(S.base,(S.StackLength+StackIncrement)*sizeof(SEle mType));S.top=S.base+S.StackLength;S.StackLength += StackIncrement;}S.top->di=e.di; S.top->ord=e.ord; S.top->seat.x=e.seat.x; S.top->seat.y=e.seat.y;S.top++;return true;}bool Pop(Stack &S,SElemType &e){ //将栈顶元素取出,赋值给eif(S.base==S.top)return false;S.top--;e.di=S.top->di; e.ord=S.top->ord; e.seat.x=S.top->seat.x;e.seat.y=S.top->seat.y;return true;}bool StackEmpty(Stack s){ //判断栈是否为空return !(s.top-s.base);}bool Pass(Seat s){ //判断当前位置是否通return Map[s.x][s.y];}bool FootPrint(Seat s){ // 在此位置留下标记,表示已经经过is_through[s.x][s.y]=true;return true;}Seat NextPos(Seat s,int i){ // 将当前位置指向逻辑上的下个位置,指向的方向由i确定Seat ss;if(i==1){ss.x=s.x+1; ss.y=s.y;}elseif(i==2){ss.x=s.x; ss.y=s.y+1;}elseif(i==3){ss.x=s.x-1; ss.y=s.y;}else{ss.x=s.x; ss.y=s.y+1;}return ss;}bool MazePath(Seat start,Seat end){InitStack(S); //创建栈并且初始化Seat curpos; curpos.x=start.x; curpos.y=start.y; //设定当前位置为入口地址int curstep=1; // 探索第一步do{if(Pass(curpos)&&!is_through[curpos.x][curpos.y]){ // 当前位置通且没有来过FootPrint(curpos); // 留下痕迹SElemType e; // 构建入栈信息e.di=1; e.ord=curstep; e.seat.x=curpos.x; e.seat.y=curpos.y;Push(S,e); // 加入路径if((curpos.x==end.x)&&(curpos.y==end.y)) // 到达终点return true;curpos=NextPos(curpos,1); // 探索下一步curstep++;}else{ // 当前位置不通,将前面一个位置取出,改由其他方向在判断SElemType e;if(!StackEmpty(S)){Pop(S,e);while(e.di==4&&!StackEmpty(S)){FootPrint(e.seat); Pop(S,e); // 如果这个位置的其他四个方向都不满足,表示这个位置不可取,取出栈并且留下标识}if(e.di<4){ // 如果其他方向还没有探索完,继续探索下一个方向e.di++; Push(S,e);curpos=NextPos(e.seat,e.di);}}}}while(!StackEmpty(S));return false;}int main(){int i,j;Seat sta,end;sta.x=1; sta.y=1; end.x=8; end.y=8;MazePath(sta,end);SElemType *b=S.base;printf("迷宫地图为(1表示通,0表示不通):\n");for(i=0;i<10;i++){for(j=0;j<10;j++)printf("%d ",Map[i][j]);printf("\n");}printf("迷宫路径为:");while(b!=S.top){printf("(%d,%d) -> ",b->seat.x,b->seat.y);++b;}printf("出口\n");scanf("%d",i);return 0;}。

(完整word版)c语言迷宫最完整做法

(完整word版)c语言迷宫最完整做法

#include〈stdio。

h〉#include〈stdlib。

h>#include〈time.h>#define stack_init_size 200#define stack_increment 10#define ERROE 0#define TRUE 1#define FALSE 0#define OVERFLOW 0#define OK 1typedef int Status;typedef struct{int x;int y;}PosType;typedef struct {int ord; // 通道块在路径上的“序号”PosType seat; //通道块在迷宫中的“坐标位置”int di; //从此通道块走向下一通道块的“方向”}SElemType;typedef struct{SElemType *base;SElemType *top;int stacksize;}SqStack;int mg[20][20];/*随机生成迷宫的函数/*为了能够让尽量能通过,将能通过的块和不能通过的块数量比大致为2:1*/void Random(){int i,j,k;srand(time(NULL));mg[1][0]=mg[1][1]=mg[18][19]=0; //将入口、出口设置为“0"即可通过for(j=0;j〈20;j++)mg[0][j]=mg[19][j]=1;/*设置迷宫外围“不可走”,保证只有一个出口和入口*/ for(i=2;i〈19;i++)mg[i][0]=mg[i—1][19]=1; /*设置迷宫外围“不可走”,保证只有一个出口和入口*/ for(i=1;i〈19;i++)for(j=1;j<19;j++){k=rand()%3; //随机生成0、1、2三个数if(k)mg[i][j]=0;else{if((i==1&&j==1)||(i==18&&j==18)) /*因为距入口或出口一步的路是必经之路,故设该通道块为“0”加大迷宫能通行的概率*/mg[i][j]=0;elsemg[i][j]=1;}}}//构造一个空栈Status InitStack(SqStack &s){s。

迷宫求解源程序

迷宫求解源程序

附录(源程序清单包括递归与非递归算法)递归算法#include <stdio.h>#include <stdlib.h>int visit(int, int);int maze[7][7] = {{2, 2, 2, 2, 2, 2, 2},{2, 1, 1, 1, 1, 1, 2},{2, 1, 2, 1, 2, 1, 2},{2, 1, 1, 2, 1, 2, 2},{2, 2, 1, 2, 1, 2, 2},{2, 1, 1, 1, 1, 1, 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("█");elseprintf(" ");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] == 0)printf("◇");elseprintf(" ");}printf("\n");}}return 0;}int visit(int i, int j) {maze[i][j] = 0;if(i == endI && j == endJ)success = 1;if(success != 1 && maze[i][j+1] == 1) {printf("向右");visit(i, j+1);}if(success != 1 && maze[i+1][j] == 1) { printf("向下");visit(i+1, j);}if(success != 1 && maze[i][j-1] == 1){printf("向左"); visit(i, j-1);}if(success != 1 && maze[i-1][j] == 1){printf("向上");visit(i-1, j);}if(success != 1)maze[i][j] = 1;return success;}说明由于迷宫的设计,走迷宫的入口至出口路径可能不只一条,解法求所有路径看起来复杂但其实更简单,只要走至出口时显示经过的路径,然后退回上一格重新选择下一个位置继续递回就可以了,比求出单一路径还简单,我的程序只要作一点修改就可以了。

递归与非递归实现走迷宫算法

递归与非递归实现走迷宫算法

递归与⾮递归实现⾛迷宫算法●问题描述: 给出⼀个矩阵,其中0表⽰通路,1表⽰墙壁,这样就形成了⼀个迷宫,要求编写算法求出其中⼀条路径。

●递归思路: 编写⼀个⾛迷宫函数,传⼊⼆位数组的下标,先假设该点位于最终路径上(将0置为2)再探测周围四个点是否可以⾛通(是否为0),如果可以⾛通则将该点四周能⾛通的点作为函数参数传⼊函数进⼊递归。

若四周均不能⾛通(都不为0时)则将该点置回0表⽰该点不是最终路径上的点。

在此思路中递归进⼊时表⽰了枚举路径,当发现此条路径⾛到某处再不能⾛通时就将路径该点置回0并且递归退出(回溯)寻找下⼀条可⾛通路径。

●代码:#include <stdio.h>#include <stdlib.h>#define END_I 8#define END_J 7#define START_I 0#define START_J 0//⾛迷宫int VistMaze(int maze[][8], int i, int j){int end = 0;//假设能够⾛通maze[i][j] = 2;//如果到达重点则将end置为0表⽰迷宫已经⾛结束if (i == END_I && j == END_J){end = 1;}//如果迷宫没有⾛结束则将搜索所在位置的右、下、左、上四个⽅向是否能够⾛通if (end != 1 && j + 1 <= END_J && maze[i][j + 1] == 0){ //右if (VistMaze(maze, i, j + 1) == 1)return 1;}if (end != 1 && i + 1 <= END_I && maze[i + 1][j] == 0){ //下if (VistMaze(maze, i + 1, j) == 1)return 1;}if (end != 1 && j - 1 >= START_J && maze[i][j - 1] == 0){ //左if (VistMaze(maze, i, j - 1) == 1)return 1;}if (end != 1 && i - 1 >= START_I && maze[i - 1][j] == 0){ //上if (VistMaze(maze, i - 1, j) == 1)return 1;} //当四周都不通的时候将其置回0if (end != 1){maze[i][j] = 0;}return end;}int main(void){//迷宫int i, j;int maze[9][8] = {{0,0,1,0,0,0,1,0},{0,0,1,0,0,0,1,0},{0,0,0,0,1,1,0,1},{0,1,1,1,0,0,1,0},{0,0,0,1,0,0,0,0},{0,1,0,0,0,1,0,1},{0,1,1,1,1,0,0,1},{1,1,0,0,1,1,0,1},{1,1,0,0,0,0,0,0}};//打印出迷宫printf("原迷宫:\n");for(i = 0; i <= 9; i++)printf("-");printf("\n");for (i = 0; i < 9; i++){printf("|");for (j = 0; j < 8; j++){if (maze[i][j] == 1)printf("@");elseprintf(" ");}printf("|\n");}for(i = 0; i <= 9; i++)printf("-");printf("\n");if (VistMaze(maze, 0, 0) == 0){printf("没有路径可⾛\n");exit(0);}//打印出迷宫和路径printf("迷宫和路径:\n");for(i = 0; i <= 9; i++)printf("-");printf("\n");for (i = 0; i < 9; i++){printf("|");for (j = 0; j < 8; j++){if (maze[i][j] == 1)printf("@");else if (maze[i][j] == 2)printf("%%");elseprintf(" ");}printf("|\n");}for(i = 0; i <= 9; i++)printf("-");printf("\n");return 0;}●⾮递归思路: 此题也可以使⽤栈来避开递归,⾸先需要开辟⼀个和迷宫具有同样⼏何形状的结构体⼆维数组来保存是从哪⼀个点(坐标)到达该点的(该初始化时将所有的坐标都置为-1),还需要⼀个可以保存坐标的栈。

[迷宫中的算法实践]迷宫生成算法——递归分割算法

[迷宫中的算法实践]迷宫生成算法——递归分割算法

[迷宫中的算法实践]迷宫⽣成算法——递归分割算法Recursive division methodMazes can be created with recursive division, an algorithm which works as follows: Begin with the maze's space with no walls. Call this a chamber. Divide the chamber with a randomly positioned wall (or multiple walls) where each wall contains a randomly positioned passage opening within it. Then recursively repeat the process on the subchambers until all chambers are minimum sized. This method results in mazes with long straight walls crossing their space, making it easier to see which areas to avoid.For example, in a rectangular maze, build at random points two walls that are perpendicular to each other. These two walls divide the large chamber into four smaller chambers separated by four walls. Choose three of the four walls at random, and open a one cell-wide hole at a random point in each of the three. Continue in this manner recursively, until every chamber has a width of one cell in either of the two directions.Recursive Maze generation递归分割算法可以⽤递归分割法创建迷宫,算法的⼯作原理如下:1.开始创建迷宫,使整个空间没有壁,我们称之为“室”。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

// algo3-9.cpp 用递归函数求解迷宫问题(求出所有解)
#include<stdio.h> // 根据《PASCAL程序设计》(郑启华编著)中的程序改编
struct PosType // 迷宫坐标位置类型
{
int x; // 行值
int y; // 列值
};
#define MAXLENGTH 25 // 设迷宫的最大行列为25
typedef int MazeType[MAXLENGTH][MAXLENGTH]; // [行][列]
// 全局变量
PosType end; // 迷宫终点位置
MazeType m; // 迷宫数组
int x,y; // 迷宫行数,列数
// 定义墙元素值为0,可通过路径为-1,通过路径为足迹
void Print(int x,int y)
{ // 输出解
int i,j;
for(i=0;i<x;i++)
{
for(j=0;j<y;j++)
printf("%3d",m[i][j]);
printf("\n");
}
printf("\n");
}
void Try(PosType cur,int curstep)
{ // 由当前位置cur、当前步骤curstep试探下一点
int i;
PosType next; // 下一个位置
PosType direc[4]={{0,1},{1,0},{0,-1},{-1,0}}; // {行增量,列增量} // 移动方向,依次为东南西北
for(i=0;i<=3;i++) // 依次试探东南西北四个方向
{
next.x=cur.x+direc[i].x; //下一点的行坐标
next.y=cur.y+direc[i].y; //下一点的列坐标
if(m[next.x][next.y]==-1) // 是通路
{
m[next.x][next.y]=++curstep;
if(next.x!=end.x||next.y!=end.y) // 没到终点
Try(next,curstep); // 试探下一点(递归调用)
else
Print(x,y); // 输出结果
m[next.x][next.y]=-1; // 恢复为通路,试探下一条路 curstep--;
}
}
}
int main()
{
PosType begin;
int i,j,x1,y1;
printf("请输入迷宫的行数,列数(包括外墙):");
scanf("%d,%d",&x,&y);
for(i=0;i<x;i++) // 定义周边值为0(同墙)
{
m[0][i]=0; // 行周边
m[x-1][i]=0;
}
for(j=1;j<y-1;j++)
{
m[j][0]=0; // 列周边
m[j][y-1]=0;
}
for(i=1;i<x-1;i++)
for(j=1;j<y-1;j++)
m[i][j]=-1; // 定义通道初值为-1
printf("请输入迷宫内墙单元数:");
scanf("%d",&j);
if(j)
printf("请依次输入迷宫内墙每个单元的行数,列数:\n"); for(i=1;i<=j;i++)
{
scanf("%d,%d",&x1,&y1);
m[x1][y1]=0;
}
printf("迷宫结构如下:\n");
Print(x,y);
printf("请输入起点的行数,列数:");
scanf("%d,%d",&begin.x,&begin.y); printf("请输入终点的行数,列数:");
scanf("%d,%d",&end.x,&end.y);
m[begin.x][begin.y]=1;
Try(begin,1); // 由第一步起点试探起 }。

相关文档
最新文档