栈的思想用于求解迷宫问题
来源:互联网 发布:ubuntu 分辨率不能调 编辑:程序博客网 时间:2024/05/21 14:55
迷宫问题是一个经典的问题,当迷宫规模较大时,手工求解是十分困难的,所以用善于进行重复繁琐计算的计算机来求解便十分合适。基本思想和解决“八皇后问题” 的思想一致,都是利用回溯法。从入口开始,探索每一个迷宫中没有被墙挡住的位置,如果该位置可以移动到下一个位置,则标记该位置已被探索过并入栈;如果不能移动到下一位置,则标记为探索失败并回退到上一个位置,如果最终退回了出发点,则说明迷宫无解。下面附上代码:
#include<stdio.h>#include<stdlib.h>#include<time.h>#define OK 1#define ERROR 0#define TRUE 1#define FALSE 0#define passed 2#define failed 3#define N 2//定义迷宫规模#define NUM (N+2)//定义迷宫总宽度/*迷宫中为1的地方为墙壁,0为可到达的点*/ typedef int status;typedef int elemtype;/*定义位置pos*/ typedef struct pos{ elemtype x; elemtype y; elemtype next;//当前位置的下一个位置 }pos;typedef struct sqstack{ pos p[N*N]; int top;}sqstack;int maze[NUM][NUM];//定义迷宫 /*定义栈操作*/ status initstack(sqstack *S){ S->top=-1;}status stacklength(sqstack *S){ return S->top+1;}status push(sqstack *S,pos p){ S->top++; S->p[S->top]=p;}status pop(sqstack *S){ S->top--;}status gettop(sqstack *S,pos *p){ *p=S->p[S->top];}status emptystack(sqstack *S){ if(S->top==-1) return TRUE; else return FALSE;}/*其他操作*//*********************************/ /*设定位置*/status setpos(pos *p,elemtype x,elemtype y){ p->x=x; p->y=y; }/*设定下一位置next*/ status setnext(pos *p,elemtype next){ p->next=next;}/*判断是否可以到达下一个位置*/status hasnext(pos *p){ int x=0,y=0; p->next=0;//p->next用于八个方向的确定 while(p->next<8){ p->next++; /*这部分代码用来让pos在附近的八个位置移动,以判断是否能到达下一位置*/ switch(p->next){ case 1: x=p->x+1; y=p->y+1; break; case 2: x=p->x+1; y=p->y-1; break; case 3: x=p->x-1; y=p->y+1; break; case 4: x=p->x-1; y=p->y-1; break; case 5: x=p->x+1; y=p->y; break; case 6: x=p->x; y=p->y+1; break; case 7: x=p->x-1; y=p->y; break; case 8: x=p->x; y=p->y-1; break; } /*判断移动之后的位置能否到达*/ if(maze[x][y]==0){ p->x=x; p->y=y; p->next=0; return OK; } } return ERROR;//不能到达,返回ERROR }/*标记探索过且能通过的点*/status markpassedpoint(pos *p){ maze[p->x][p->y]=passed;} /*标记无路可走的点*/status markfailedpoint(pos *p){ maze[p->x][p->y]=failed;}/*判断出口*/status isexit(pos *p){ if(p->x==N&&p->y==N) return TRUE; return FALSE;}/*生成迷宫*/status makemaze(void){ int i=0,j=0; srand(time(0)); for(i=0;i<NUM;i++){ for(j=0;j<NUM;j++){ if(i==0||i==NUM-1||j==0||j==NUM-1)//迷宫四周的墙 maze[i][j]=1; else maze[i][j]=rand()%2; } } maze[1][1]=maze[NUM-2][NUM-2]=0;//定义出入口 }/*打印迷宫*/status printmaze(void){ int i=0,j=0; for(i=0;i<NUM;i++){ for(j=0;j<NUM;j++){ printf("%d ",maze[i][j]); } printf("\n"); } printf("\n");} /*打印路径*/status printway(sqstack *S){ int i=0; printf("The avalible way is:\n"); for(i=0;i<S->top;i++) printf("<%d,%d>->",S->p[i].x,S->p[i].y); printf("<%d,%d>",S->p[i].x,S->p[i].y);//分开写的目的是让最后一项不出现-> }/*搜索路径*/status searchway(){ sqstack S; pos p; initstack(&S); setpos(&p,1,1);//设置初始位置为(1,1) setnext(&p,0);//设初始位置下一位置可到达 push(&S,p); markpassedpoint(&p); /*栈不空是取最上方点进行判断,判断是否为出口*/ while(!emptystack(&S)){ gettop(&S,&p); if(isexit(&p)){ printway(&S); return OK; } if(hasnext(&p)){ push(&S,p); markpassedpoint(&p); } else{ pop(&S); markfailedpoint(&p); } } return ERROR;//最终回到了出发点,返回ERROR表示无解 }status main(void){ sqstack S; pos p; initstack(&S); makemaze(); printf("The Maze is:\n"); printmaze(); if(!searchway()){ printf("\nNo Avalible Ways\n"); }}
2016-04-14更新:
今天在测试自己写的迷宫的过程中,觉得每次用随机数生成的迷宫常常无解,此时就必须要亲自动手才能让程序重新生成迷宫然后重新寻找路径,十分麻烦。于是我对主程序进行了修改,让其只有在生成一个有解的迷宫后再输出答案(我真机智……)代码如下:
int main(void){ stack S; pos p; makemaze(); printf("The Maze is:\n"); printmaze(); if(!searchway()){/*如果没找到路*/ while(!searchway()){ makemaze();/*重新生成迷宫*/ printmaze(); } } }
0 0
- 栈的思想用于求解迷宫问题
- 回溯法和栈的思想用于“八皇后问题”的求解
- 迷宫问题的求解
- 用栈的思想写的动态迷宫求解
- 栈求解迷宫问题
- 栈求解迷宫问题
- 基于栈操作的迷宫问题求解
- 迷宫问题的递归求解
- 简单迷宫问题的求解
- 一般迷宫问题的求解
- 用栈求解迷宫问题 ~~
- 栈实现迷宫求解问题
- 利用栈求解迷宫问题
- 栈-迷宫求解路径问题
- 求解:栈的应用 深度优先搜索:迷宫问题
- 迷宫求解问题-递归(栈的应用)
- 栈的应用——迷宫求解问题
- 栈的应用——求解迷宫问题
- 【Delay】常用的延迟函数
- android studio运行时报错the selected device is incompatible
- 下拉菜单
- 宏基 F5 572g 预装win10改win7
- 一些不常被注意到的Java问题
- 栈的思想用于求解迷宫问题
- Netty线程模型
- Swift写简易计算器
- UVa 514 Rails
- 欢迎使用CSDN-markdown编辑器
- RPC Learn
- 前端开发学习笔记04---JavaScript
- 欧拉函数的两种实现
- android:paddingBottom=“@dimen/activity_horizontal_margin"的意思