基于栈的c语言迷宫问题与实现 (2)
用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语⾔实现简单的数据结构迷宫实验,供⼤家参考,具体内容如下分析:迷宫实验主要有两部分操作,其⼀是对迷宫的⽣成,其⼆是寻路使⽤栈的操作。
步骤:⼀、.h⽂件1、⾸先是迷宫的⽣成,可以使⽤随机数种⼦⽣成,但主要逻辑部分并不在此,所以在这⾥直接写死,固定下来。
定义⼀个坐标类型的结构体,和⼆维数组迷宫:typedef struct {int x;int y;}Pos;//迷宫类型typedef struct {int square[10][10] ={{1,1,1,1,1,1,1,1,1,1},{1,0,0,0,0,0,0,0,0,1},{1,1,1,1,0,1,1,1,0,1},{1,0,0,0,0,1,0,1,0,1},{1,0,1,1,1,1,0,1,1,1},{1,0,0,0,0,1,0,0,0,1},{1,0,1,1,0,0,0,1,0,1},{1,0,1,1,1,0,1,1,1,1},{1,0,0,0,1,0,0,0,0,1},{1,1,1,1,1,1,1,1,1,1},};}Maze;typedef Pos SElemType;2、然后是对栈的声明,栈⾥储存的元素为坐标类型//顺序栈#define MAXSIZE 50typedef struct {SElemType *base;SElemType *top; //栈顶指针int stacksize;}SqStack;3、栈操作函数声明typedef int Status;#define OK 1;#define ERROR 0;//栈的相关操作//初始化栈Status initStack(SqStack &s);//压栈Status push(SqStack &s, SElemType e);//出栈SElemType pop(SqStack &s);//清空栈Status clearStack(SqStack &s);//摧毁栈void destroyStack(SqStack &s);//遍历栈Status stackTravel(SqStack s);4、迷宫操作函数声明//初始化迷宫(同时⽣成起始点和终点)void initMaze(Maze &maze);//寻找出路;传⼊⼀个迷宫和栈找出出路void findWay(Maze &maze,SqStack &s);//判断该点的四个⽅向是否有通路,有就前进Pos isExit(Pos p, Maze maze);⼆、.cpp⽂件1、导⼊所需头⽂件#include "pch.h"#include <iostream>#include<time.h>#include<stdlib.h>using namespace std;2、栈操作实现//构造空栈Status initStack(SqStack &s) {s.base = new SElemType[MAXSIZE];if (!s.base){exit(OVERFLOW);//分配失败}s.top = s.base;s.stacksize = MAXSIZE;return OK;}//⼊栈Status push(SqStack &s, SElemType e) {//判断栈满if (s.top-s.base == s.stacksize){return ERROR;}//存⼊元素,*为取指针的值s.top++;*s.top = e;return OK;}//出栈,⽤e返回栈顶值SElemType pop(SqStack &s) {SElemType e;//判断栈为空if (s.top == s.base){//若为空则返回⼀个(-1,-1)的点,判断由外部调⽤时进⾏ e.x = -1;e.y = -1;return e;}e = *s.top;s.top--;return e;}Status clearStack(SqStack &s) {s.top = s.base;return OK;}void destroyStack(SqStack &s) {s.top = NULL;s.stacksize = 0;free(s.base);}Status stackTravel(SqStack s) {while (s.top != s.base){s.base++;Pos p = *s.base;if ( p.x == 0 || p.y == 0|| p.x == 9 ||p.y == 9){//终点输出为“End”cout << "End";}}cout << endl;return 0;}3、迷宫操作实现///////////////////////////////////////迷宫操作//////////////////////////////////初始化函数,传⼊⼀个迷宫,随机⽣成起点和终点,由于起点有⼀定限制,所以这⾥起点也固定为⼏个最合适的点void initMaze(Maze &maze) {//⽣成随机数srand((unsigned)time(NULL));int index = rand() % 36 + 1;int start = index % 6 + 1;//⽣成起始点数值为‘s'switch (start){case 1:maze.square[1][1] = 's';break;case 2:maze.square[3][8] = 's';break;case 3:maze.square[3][6] = 's';break;case 4:maze.square[6][8] = 's';break;case 5:maze.square[8][3] = 's';break;case 6:maze.square[8][8] = 's';break;}//随机⽣成终点'e'表⽰while (index = rand()%36+1){//出⼝在顶部if (index >1 &&index<10 && maze.square[1][index-1]!='s'){maze.square[0][index-1] = 'e';break;}//出⼝在右侧else if (index>10 &&index <19){if (maze.square[index-10][8] != 1 && maze.square[index-10][8]!='s') {maze.square[index-10][9] = 'e';break;}}//底部出⼝else if (index >19&&index<28){if (maze.square[8][index - 19] != 's' && maze.square[8][index - 19] != 1) {maze.square[9][index - 19] = 'e';break;}}//左侧出⼝else if (index >28 && index <=36){if (maze.square[index-28][1] != 1 &&maze.square[index-28][1] != 's'){maze.square[index - 28][0] = 'e';break;}}}void showMaze(Maze maze) {for (int i = 0; i < 10; i++){for (int j = 0; j < 10; j++){if (maze.square[i][j] == 1){cout << "* ";}else if (maze.square[i][j] == 0){cout << " ";}else{cout << (char)maze.square[i][j]<<" ";}}cout << endl;}}//寻找迷宫路径void findWay(Maze &maze,SqStack &s) {//⾸先遍历找出起始点和终点并保存下来Pos start,end;for (int i = 0; i < 10; i++){for (int j = 0; j < 10; j++) {if (maze.square[i][j] == 's'){ //起点压⼊栈内start.x = i;start.y = j;push(s, start);}else if (maze.square[i][j] == 'e'){ //出⼝end.x = i;end.y = j;}}}//寻找路径Pos go = start;//直到找到出⼝才结束while ( s.top->x != end.x || s.top->y != end.y){//获得下⼀步坐标Pos path = isExit(go, maze);if (path.x != go.x || path.y != go.y){//前进maze.square[path.x][path.y] = 'p';push(s, path);go = path;}//如果所有放向都⾛不通(即返回的点是传⼊的点),则将其标为“@”,出栈到上⼀个点,继续判断else{//⾛不通popmaze.square[path.x][path.y] = '@';pop(s);go = *s.top;}}maze.square[end.x][end.y] = 'e';}//判断返回下⼀步路径(顺序:右下左上),传⼊所处位置,从右边开始判断是否⼜通路或者出⼝,有就返回哪个⽅向上的点Pos isExit(Pos p,Maze maze) {Pos tempP = p;if (maze.square[tempP.x][tempP.y+1] == 0 || maze.square[tempP.x][tempP.y + 1] == 'e'){tempP.y++;else if(maze.square[tempP.x+1][tempP.y] == 0 || maze.square[tempP.x +1][tempP.y] == 'e'){tempP.x++;}else if (maze.square[tempP.x][tempP.y - 1] == 0 || maze.square[tempP.x][tempP.y - 1] == 'e'){tempP.y--;}else if (maze.square[tempP.x - 1][tempP.y] == 0 || maze.square[tempP.x - 1][tempP.y] == 'e'){tempP.x--;}return tempP;}三、main函数调⽤int main(){while (true){//创建⼀个迷宫Maze maze;initMaze(maze);//初始化⼀个栈SqStack S;initStack(S);cout << "*****************************" << endl;cout << "* 1、⽣成迷宫 2、退出 *" << endl;cout << "*****************************" << endl;cout << "请输⼊你的选择:";int select = 0;cin >> select;if (select == 1){cout << "⽣成随机起点和出⼝迷宫:" << endl;showMaze(maze);cout << "⽣成迷宫路径:" << endl;findWay(maze, S);stackTravel(S);showMaze(maze);cout << endl;}if (select == 2){clearStack(S);break;}}return 0;}四、评价这是个叫简易的迷宫,但基本实现了迷宫的寻路逻辑,可改进的地⽅有:1、因为很多地⽅写死了,所以复⽤性不⾼,可以⽤循环遍历来随机⽣成起点,同理迷宫的⽣成也是这样2、判断路径可以⽤递归调⽤实现前进逻辑以上就是本⽂的全部内容,希望对⼤家的学习有所帮助,也希望⼤家多多⽀持。
用栈方法、队列方法求解迷宫问题

目录1 前言 ................................................ 1.2 需求分析 ............................................ 1..2.1 课程设计目的 ................................. 1.2.2课程设计任务 ................................. 1.2.3 设计环境 ..................................... 1.. 3 概要设计 ............................................ 1..3.1数据结构设计 ................................. 1.3.2 模块设计 ..................................... 2.. 4 详细设计 ............................................ 3..5 测试分析6 课程设计总结 参考文献 ............................................. 8 .........4.1 数据类型的定义 ................. 错 误. !未定义书签 4.2 主要模块的算法描述 ............ 错 误!未定义书签 .6.. 7.. 附 录(程序代码实现 )............................................ 9 ....致谢................................................ 8......... 1前言设计一个简单迷宫程序,从入口出发,按某一方向向前探索,若能走通(未走过的),即某处可以到达,则到达新点,否则试探下一方向;若所有方向均没有通路,则沿原点返回前一点,换下一个方向在继续试探,直到所有可能的通路都探索到,或找到一条通路,或无路可走又返回到入口点。
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,结束函数,此时栈中已储存了通往终点的路径,若没有通路,则弹出栈顶元素,根据递归原理该路径上的所有点都会弹出并标记未⾛,回溯到之前的点,继续向其他⽅向搜索,直到找到终点或遍历完整个图。
用栈解决迷宫问题

⽤栈解决迷宫问题⼀、因为栈是后进先出的特性,所以说⼀般⽤栈都是通过dfs来解决迷宫问题。
如果⽤队列的话就是通过bfs来解决。
⼆、c++代码:1 #include<iostream>2 #include<cstdio>3 #include<stdio.h>4 #include<string.h>5 #include<windows.h>6using namespace std;7const int maxn=1005;8#define MaxSize 100005 //栈最多元素个数9int M=4,N=4;10int w[6][6]=11 {12 {1,1,1,1,1,1}13 ,{1,0,0,0,1,1}14 ,{1,0,1,0,0,1}15 ,{1,0,0,0,1,1}16 ,{1,1,0,0,0,1}17 ,{1,1,1,1,1,1}18 };19int mg[maxn][maxn];20char s[maxn][maxn];21struct migong22 {23int i; //路径横坐标24int j; //路径纵坐标25int di; //⽅向26 } Stack[MaxSize],Path[MaxSize]; //定义栈和存放最短路径的数组27int top=-1; //栈顶指针28int counts=1; //路径数计数29int minlen=MaxSize; //最短路径长度30void mgpath() //路径为:(1,1)->(M,N)31 {32int i,j,di,finds,k;33 top++;34 Stack[top].i=1;35 Stack[top].j=1;36 Stack[top].di=-1;37 mg[1][1]=-1; //初始结点进栈38while(top>-1) //栈不空时循环39 {40 i=Stack[top].i;41 j=Stack[top].j;42 di=Stack[top].di;43if(i==M && j==N) //找到了出⼝,输出路径44 {45// cout<<counts<<": ";46// counts++;47// for(k=0; k<=top; k++)48// {49// cout<<"("<<Stack[k].i<<","<<Stack[k].j<<")"<<" ";50//51// }52// cout<<endl;53if(top+1<minlen) //⽐较输出最短路径54 {55for(k=0; k<=top; k++)56 Path[k]=Stack[k];57 minlen=top+1;58 }59 mg[Stack[top].i][Stack[top].j]=0; //让该位置变为其他路径的可⾛结点60 top--;61 i=Stack[top].i;62 j=Stack[top].j;63 di=Stack[top].di;64 }65 finds=0;66while(di<4 && finds==0) //找下⼀个可⾛结点67 {68 di++;69switch(di)70 {71case0:72 i=Stack[top].i-1;73 j=Stack[top].j;74break; //上⾯75case1:76 i=Stack[top].i;77 j=Stack[top].j+1;78break; //右边79case2:80 i=Stack[top].i+1;82break; //下⾯83case3:84 i=Stack[top].i;85 j=Stack[top].j-1;86break; //左边87 }88if(mg[i][j]==0) //因为地图外边围了⼀层墙,所以不需要判断边界89 finds=1;90 }91if(finds == 1) //找到了下⼀个可⾛结点92 {93 Stack[top].di=di; //修改原栈顶元素的di值94 top++; //下⼀个可⾛结点进栈95 Stack[top].i=i;96 Stack[top].j=j;97 Stack[top].di=-1;98 mg[i][j]=-1; //避免重复⾛到该结点99 }100else101 {102 mg[Stack[top].i][Stack[top].j]=0; //让该位置变为其他路径的可⾛结点103 top--;104 }105 }106 cout<<"最短路径如下(输出结果以坐标显⽰)"<<endl;107 cout<<"长度: "<<minlen<<endl;108 cout<<"路径: "<<endl;109for(k=0; k<minlen; k++)110 {111 cout<<"("<<Path[k].i<<","<<Path[k].j<<")"<<"";112 }113 }114int main()115 {116int x;117while(1)118 {119 system("cls");120 printf ( " 迷宫系统 \n");121 printf ( " \n");122 printf ( " \n");123 printf ("-------------------------------------- \n");124 printf ("--------------------------------------\n");125 printf ("--------⼁[0]重构地图⼁---\n");126 printf ("--------⼁[1]使⽤默认地图⼁---\n");127 printf ("--------⼁[2]结束⼁---\n");128 printf ("----------输⼊相应数字----------------\n");129 printf ("--------------------------------------- \n");130 printf ( " \n");131 printf ( " \n");132 scanf("%d",&x);133if(x==0)134 {135 system("cls");136 printf(" 重构地图\n");137 printf("输⼊内容请以空格或者换⾏分隔开,且0代表此处可⾛,1代表此处不可⾏\n"); 138 printf("\n现在请输⼊地图是⼏⾏⼏列\n");139int n,m;140 memset(mg,0,sizeof(mg));141 scanf("%d%d",&n,&m);142int flag=0;143 printf("\n请输⼊地图,请保证左上⾓和右下⾓都为0\n");144for(int i=1; i<=n; ++i)145 {146147 scanf("%s",s[i]+1);148 mg[i][0]=mg[i][m+1]=1;149 }150for(int j=1; j<=m; ++j)151 {152 mg[0][j]=mg[n+1][j]=1;153 }154for(int i=1;i<=n;++i)155 {156for(int j=1;j<=m;++j)157 {158 mg[i][j]=s[i][j]-'0';159 }160 }161 M=n;162 N=m;163164//cout<<"迷宫所有路径如下:"<<endl;165 mgpath();166 system("pause");167 }168else if(x==1)169 {171 M=N=4;172for(int i=0; i<6; ++i) 173 {174for(int j=0; j<6; ++j) 175 {176 mg[i][j]=w[i][j]; 177 }178 }179 mgpath();180 system("pause"); 181 }182else break;183 }184return0;185 }View Code。
基于栈的应用实现解决迷宫问题论文

基于栈的应用实现解决迷宫问题论文数据结构与算法姓名:赵庶林学院及专业:航天自动化班级:0804102学号:H080410235一,问题重述:迷宫是一个矩形区域,它有一个入口和出口。
在迷宫的内部包含不能穿越的墙或障碍。
假定用n*m的矩形来描述迷宫,位置(0,0)代表入口,(n,m)表示出口,n和m分别代表迷宫的行数和列数。
迷宫中的每个位置都可用其行号和列号来指定。
在矩形中,当且仅当在位置(i,j)处有一个障碍时其值是0,否则为1,如一个迷宫对应的矩阵描述如下:1,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,1,1,0,0,1,1,1,0,0,0,1,1,1,1,1,1,1,0,1,1,1,1,1,0,1,1,1,0,1,1,1,0,0,0,1,0,0,1,0,1,1,1,1,1,1,1设计一个程序,对于此迷宫,求出一条从入口到出口的通道,或得出没有通路的结论。
二,算法的基本思想:走迷宫的过程可以模拟为一个搜索的过程:每到一处,总让它按东、南、西、北4个方向顺序试探下一个位置;如果某方向可以通过,并且不曾到达,则前进一步,在新位置上继续进行搜索;如果4个方向都走不通或曾经到达过,则退回一步,在原来的位置上继续试探下一位置。
每前进或后退一步,都要进行判断:若前进到了出口处,则说明找到了一条通路;若退回到了入口处,则说明不存在通路。
用一个字符类型的二维数组表示迷宫,数组中每个元素取值“1”(表示通路)或“0”(表示墙壁)。
迷宫的入口点在位置(0,0)处,出口点在位置(8,8)处。
设计一个模拟走迷宫的算法,为其寻找一条从入口点到出口点的通路。
构造两个栈,一个用来保存探索中的全部路径,一个用来保存有效路径。
首先把迷宫的入口作为当前位置。
如果当前位置是迷宫出口,那么已经找到了一条路径,搜索工作结束。
如果当前位置不是迷宫出口,则在当前位置上放置障碍物,以便阻止搜索过程又绕回到这个位置。
接下来检查相邻的位置中是否有空闲的(即没有障碍物),如果有,就移动到这个新的相邻位置,然后从这个位置开始搜索通往出口的路径。
基于栈实现的迷宫问题

基于栈实现的迷宫问题1、问题描述:在一个二维阵列构成的迷宫里, 数组元素仅有0和1构成,其中0表示可通行的路径, 1代表障碍。
另外,定义左上角是迷宫的入口, 右下角是迷宫的出口, 在迷宫里面只允许上下左右四个方向行走,请找出一条通路。
2、算法基本思想:由于计算机解迷宫时,通常用的是“穷举求解”的方法,即从入口出发,顺某一方向向前探索,若能走通,则继续往前走;否则沿原路退回,换一个方向再继续探索,直至所有可能的通路都探索到为止。
为了保证在任何位置上都能沿原路退回,显然需要用一个后进先出的结构来保存从入口到当前位置的路径。
因此,在求迷宫通路的算法中采用“栈”进行求解。
2.1、迷宫构建:为了避免每走一步便需判断是否走出迷宫的麻烦,将所创建的迷宫用1包围起来。
2.2、位置搜索:每到一处,总让它按上、下、左、右4个方向试探下一个位置;如果某方向可以通过,即该方向上的元素为0,则前进一步,并在新位置上继续进行搜索;如果4个方向都走不通或曾经走过,则后退一步,在原来的位置上继续试探下一位置。
每前进一步,都要进行判断:若前进到了出口处,则说明找到了一条通路;若退回到了入口处,则说明不存在通路。
3、算法运行环境:VC++6.04、主要函数:Mazepath函数:求解迷宫maze中,从入口start到出口end的一条路径若存在,返回TRUE,否则返回FALSEInitMaze函数:创建初始矩阵按照用户输入的数据构建0/1矩阵,并在矩阵四周添加一圈1作为围墙。
Pass函数:判断当前节点能否通过。
FootPrint函数:对于走过的节点用'*' 进行标记。
MarkPrint函数:对于不能通过的节点用'#' 进行标记。
Nextpos函数;返回当前节点的下一结点,对应东、西、南、北四个方向。
Printmaze 函数:打印迷宫信息,存在的通路用'*' 表示。
5、算法举例:5.1、输入的矩阵:运行结果:5.2、输入的矩阵:运行结果:没有找到通路6、算法复杂度分析:(n为迷宫的行数,m为迷宫的列数)走迷宫的时间复杂度:O(n*m*2)。
顺序栈和迷宫求解(C语言)

顺序栈和迷宫求解(C语⾔)顺序栈 根据《数据结构》书中的讲解,对顺序栈的⼀个基本实现。
define.h1// define.h2 #ifndef __MENGQL_DEFINE__3#define __MENGQL_DEFINE__45#define C_LOG_DBG(format, ...)6//printf("[%s@%s,%d] " format ,__FUNCTION__, __FILE__, __LINE__, ##__VA_ARGS__);7#define C_LOG_ERR(format, ...) printf("[%s@%s,%d] " format ,__FUNCTION__, __FILE__, __LINE__, ##__VA_ARGS__);8 typedef enum EStatus {ERROR, OK} Status;910#endifSqStack.h1// SqStack.h2 #ifndef __SQ_STACK_H__3#define __SQ_STACK_H__4 #include "define.h"56 typedef struct7 {8int x;9int y;10 }PosType;1112 typedef struct13 {14int ord;15 PosType seat;16int di;17 }SElemType;1819#define STACK_INIT_SIZE 10020 typedef struct21 {22 SElemType* base;23 SElemType* top;24int stacksize;25 }SqStack;2627extern Status InitStack(SqStack *S);28extern Status GetTopStack(SqStack S, SElemType *e);29extern Status PushStack(SqStack *S, SElemType e);30extern Status PopStack(SqStack *S, SElemType *e);31extern Status StackEmpty(SqStack *S);32extern Status DestoryStack(SqStack *S);33#endifSqStack.c1// SqStack.c2 #include "define.h"3 #include "SqStack.h"4 #include <stdlib.h>5 #include <stdio.h>6 Status InitStack(SqStack *S)7 {8 S->stacksize = STACK_INIT_SIZE;9 S->base = (SElemType *)malloc(S->stacksize * sizeof(SElemType));10if(S->base == NULL)11 {12 C_LOG_ERR("%s\n","MALLOC OVERFLOW");13return ERROR;14 }15 S->top = S->base;1617return OK;18 }19 Status GetTopStack(SqStack S, SElemType *e)20 {21if(S.top == S.base)22 {23 C_LOG_ERR("%s\n","STACK IS EMPTY");24return ERROR;25 }26 *e = *(S.top-1);27return OK;28 }29 Status PushStack(SqStack *S, SElemType e)30 {31if(S->top - S->base >= S->stacksize)32 {33 S->base = (SElemType *)realloc(S->base, (S->stacksize * 2) * sizeof(SElemType)); 34if(S->base == NULL)35 {36 C_LOG_ERR("%s\n","REMALLOC OVERFLOW");37return ERROR;38 }39 S->stacksize *= 2;40 }41 *(S->top++) = e;42return OK;43 }44 Status PopStack(SqStack *S, SElemType *e)45 {46if(S->top == S->base)47 {48 C_LOG_ERR("%s\n","STACK IS EMPTY");49return ERROR;50 }51 *e = *(--S->top);52return OK;53 }54 Status StackEmpty(SqStack *S)55 {56if(S->top == S->base)57 {58return OK;59 }60return ERROR;61 }62 Status DestoryStack(SqStack *S)63 {64 S->stacksize = 0;65 free(S->base);66 S->top = S->base = NULL;67return OK;68 }迷宫求解 顺序栈实现的迷宫求解是深度优先搜索,得出的路径是⾮最短路径。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
数据结构与算法实验报告基于栈的C语言迷宫问题与实现一.问题描述多年以来,迷宫问题一直是令人感兴趣的题目。
实验心理学家训练老鼠在迷宫中寻找食物。
许多神秘主义小说家也曾经把英国乡村花园迷宫作为谋杀现场。
于是,老鼠过迷宫问题就此产生,这是一个很有趣的计算机问题,主要利用“栈”是老鼠通过尝试的办法从入口穿过迷宫走到出口。
迷宫只有两个门,一个叫做入口,另一个叫做出口。
把一只老鼠从一个无顶盖的大盒子的入口处赶进迷宫。
迷宫中设置很多隔壁,对前进方向形成了多处障碍,在迷宫的唯一出口处放置了一块奶酪,吸引老鼠在迷宫中寻找通路以到达出口。
求解迷宫问题,即找出从入口到出口的路径。
一个迷宫可用上图所示方阵[m,n]表示,0表示能通过,1 表示不能通过。
现假设耗子从左上角[1,1]进入迷宫,编写算法,寻求一条从右下角[m,n] 出去的路径。
下图是一个迷宫的示意图:入口出口迷宫示意图二.算法基本思想迷宫求解问题是栈的一个典型应用。
基本算法思想是:在某个点上,按照一定的顺序(在本程序中顺序为上、右、下、左)对周围的墙、路进行判断(在本程序中分别用1、0)代替,若周围某个位置为0,则移动到该点上,再进行下一次判断;若周围的位置都为1(即没有通路),则一步步原路返回并判断有无其他通路,然后再次进行相同的判断,直到走到终点为止,或者确认没有任何通路后终止程序。
要实现上述算法,需要用到栈的思想。
栈里面压的是走过的路径,若遇到死路,则将该位置(在栈的顶层)弹出,再进行下一次判断;若遇到通路,则将该位置压栈并进行下一次判断。
如此反复循环,直到程序结束。
此时,若迷宫有通路,则栈中存储的是迷宫通路坐标的倒序排列,再把所有坐标顺序打印后,即可得到正确的迷宫通路。
三.程序具体部分的说明1.迷宫的生成根据题目的要求,迷宫的大小是自定义输入的。
所以在程序中用malloc申请动态二维数组。
数组中的元素为随机生成的0、1。
数组周围一圈的元素全部定义为1,以表示边界。
2.栈的C语言实现为了实现栈的功能,即清空、压栈、弹出、返回栈顶元素,在程序中编写了相应的函数。
MakeNULL 清空栈Push 将横、纵坐标压栈Topx 返回栈顶存储的横坐标Topy 返回栈顶存储的纵坐标Pop 弹出栈顶元素3.具体的判断算法当位置坐标(程序中为X Y)移到某一位置时,将这个位置的值赋值为1并压栈,以说明该点已经走过。
接着依次判断该点的上、右、下、左是否为0,若有一方为0,则移动到该位置上,进行下次判断;若为周围位置全部是1,则将该点压栈后不断弹出,每次弹出时判断栈顶元素(即走过的路)周围有无其他通路。
如果有的话,则选择该方向继续走下去;如果栈已经为空仍然没有找到出路,则迷宫没有出口程序结束。
当X Y走到出口坐标时,程序判断部分结束。
栈里面存储的是每个走过的点的坐标,将这些横纵坐标分别存储在两个数组中,最后将数组中的坐标元素倒序输出,即得到了完整的路径。
四.程序源代码及注释// Maze.cpp : 定义控制台应用程序的入口点。
//#include"stdafx.h"#include<stdio.h>#include<string.h>#include<malloc.h>#include<stdlib.h>#include<time.h>typedef int Elementtype;struct node{Elementtype val1;Elementtype val2;node *next;};//定义结构体typedef node *MAZE;void MakeNull(MAZE &S);void Push(Elementtype x,Elementtype y, MAZE S); void Pop(MAZE S);Elementtype Topx(MAZE S);Elementtype Topy(MAZE S);//申明函数int _tmain(int argc, _TCHAR* argv[]){int **p,*q,*x1,*y1,i,j,k,n1,n2,m1,m2,l,w,max;int x,y;int a,b,c,d;printf("输入迷宫长度及宽度l和w\n");scanf("%d %d",&l,&w);getchar();n1=w+2;n2=l+2;//为迷宫加上边界max=n1*n2;p=(int**)malloc(n1*sizeof(int));for(i=0;i<n1;i++)p[i]=(int *)malloc(n2*sizeof(int));//生成二维动态数组srand(time(NULL));x1=(int*)malloc(max*sizeof(int));//生成动态数组用于存储路径y1=(int *)malloc(max*sizeof(int));//生成动态数组用于存储路径for(i=0;i<max;i++){x1[i]=0;}for(i=0;i<max;i++){y1[i]=0;}//先将存储路径的数组元素全赋值为0for(i=0;i<n1;i++){for(j=0;j<n2;j++){if(i==0 || j==0){p[i][j]=1;}else if(i==n1-1 || j==n2-1){p[i][j]=1;}elsep[i][j]=rand()%2+0;}}//生成二维1 0随机数组p[1][1]=0;p[n1-2][n2-2]=0;//定义迷宫的入口及出口printf("生成的迷宫如下(代表墙0代表路):\n");for(i=0;i<n1;i++){{for(j=0;j<n2;j++)printf("%2d",p[i][j]);}printf("\n");}//打印迷宫MAZE S;MakeNull(S);//清空栈i=1;j=1;if(p[1][2]==1 && p[2][1]==1){printf("There is no way out");agetchar();return 0;}//判断入口是否就是死路else{do{if(p[i-1][j]==0){x=i;y=j;Push(x,y,S);p[i][j]=1;i=i-1;}//判断能否向上走else if(p[i-1][j]==1 && p[i][j+1]==0){x=i;y=j;Push(x,y,S);p[i][j]=1;j=j+1;}//判断能否向右走else if(p[i-1][j]==1 && p[i][j+1]==1 && p[i+1][j]==0) {x=i;y=j;Push(x,y,S);k=Topx(S);p[i][j]=1;i=i+1;}//判断能否向下走else if(p[i-1][j]==1 && p[i][j+1]==1 && p[i+1][j]==1 && p[i][j-1]==0){x=i;y=j;Push(x,y,S);p[i][j]=1;j=j-1;}//判断能否向左走else if(p[i-1][j]==1 && p[i][j+1]==1 && p[i+1][j]==1 && p[i][j-1]==1)//判断如果为死路{p[i][j]=1;x=i;y=j;Push(x,y,S);for(;;){Pop(S);//弹出栈顶元素x=Topx(S);y=Topy(S);//返回栈顶元素横纵坐标if( p[x-1][y]==0){i=x-1;j=y;p[i][j]=1;x=i;y=j;Push(x,y,S);break;}else if(p[x-1][y]==1 && p[x][y+1]==0){i=x;j=y+1;p[i][j]=1;x=i;y=j;Push(x,y,S);break;}else if(p[x-1][y]==1 && p[x][y+1]==1 && p[x+1][y]==0) {i=x+1;j=y;p[i][j]=1;x=i;y=j;Push(x,y,S);break;}else if(p[x-1][y]==1 && p[x][y+1]==1 && p[x+1][y]==1 && p[x][y-1]==0){i=x;j=y-1;p[i][j]=1;x=i;y=j;Push(x,y,S);break;}//判断弹出后栈顶元素周围有无通路else if(x==1 && y==1){printf("There is no way out");getchar();return 0;}//如果栈顶元素为入口则迷宫无出路}}}while(i!=n1-2 || j!=n2-2);//循环截止条件}printf("Success!\n The route is:\n");for(i=0;;i++){a=Topx(S);b=Topy(S);Pop(S);x1[i]=a;y1[i]=b;//将栈顶元素坐标存储在数组中if(a==1 && b==1){getchar();break;}}for(i=max-1;i>=0;){if(x1[i]!=0 && (x1[i]!=x1[i-1] || y1[i]!=y1[i-1])){printf("<%d ,%d> ",x1[i],y1[i]);i--;}else if(x1[i]!=0 && (x1[i]==x1[i-1] && y1[i]==y1[i-1])) {printf("<%d ,%d> ",x1[i],y1[i]);i=i-2;}elsei--;}//倒序打印数组得到顺序出路坐标printf("<%d ,%d>",n1-2,n2-2);//打印出口坐标getchar();return 0;}void MakeNull(MAZE &S) //清空栈的函数{S = new node;S->next = NULL;}void Push(Elementtype x,Elementtype y, MAZE S)//压栈函数{MAZE stk;stk = new node;stk->val1 = x;stk->val2 = y;stk->next = S->next;S->next = stk;}void Pop(MAZE S)//弹出函数{MAZE stk;if(S->next){stk = S->next;S->next = stk->next;delete stk;}}Elementtype Topx(MAZE S)//返回横坐标函数{if(S->next)return(S->next->val1);elsereturn NULL;}Elementtype Topy(MAZE S)//返回纵坐标函数{if(S->next)return(S->next->val2);elsereturn NULL;}五.程序运行结果运行程序后,首先输入迷宫的长度和宽度假设迷宫是8*8的(也可以为其他大小)。