#define _CRT_SECURE_NO_WARINGS
#include<stdio.h>
#include<stdlib.h>
#include<iostream>
#include<iomanip>
#define STACK_INIT_SIZE 1000
using namespace std;
int mazeMap[10][10] =
{
{0,0,0,0,0,0,0,0,0,0},
{0,1,0,1,1,1,1,0,1,0},
{0,0,0,1,1,1,1,0,1,0},
{0,1,0,1,0,0,0,1,1,0},
{0,1,0,1,0,1,0,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,1,0,1,0,0,1,0},
{0,0,1,1,1,1,1,1,1,0},
{0,0,0,0,0,0,0,0,0,0}
};
typedef struct
{
int row;
int col;
}posType;
typedef struct
{
int num;//通道块在路径上的序号
posType coordinate;//通道块在迷宫里的坐标
int dir;//从此通道块走向下一通道块的方向
}SElemType;
typedef struct
{
SElemType* base;
SElemType* top;
int stackSize;
}sqStack;
void PrintMaze()
{
cout << "the map of maze" << endl;
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 10; j++)
{
cout << setw(3) << mazeMap[i][j];
}
cout << endl;
}
}
void initStack(sqStack& s)
{
s.base = (SElemType*)malloc(STACK_INIT_SIZE * sizeof(SElemType));
s.top = s.base;
s.stackSize = STACK_INIT_SIZE;
}
void push(sqStack& s, SElemType& e)
{
*s.top = e;
s.top++;
}
void pop(sqStack& s, SElemType& e)
{
if (s.top == s.base)
{
return;
}
else
{
s.top--;
e = *(s.top);
}
}
bool isEmpty(sqStack s)
{
if (s.base == s.top)
{
return true;
}
else
{
return false;
}
}
void markPrint(posType pos)//留下不能通过的标记
{
cout << "(" << pos.row << "," << pos.col << ") was blocked!" << endl;
mazeMap[pos.row][pos.col] = 0;
}
void makeFootPrint(posType curPose, int curStep)
{
if (curPose.row == 1 && curPose.col == 1)
{
mazeMap[curPose.row][curPose.col] = 0;
}
else
{
mazeMap[curPose.row][curPose.col] = curStep;
}
}
bool havePass(posType curPose)//判断当前位置是0还是1
{
if (mazeMap[curPose.row][curPose.col] == 1)
{
return true;
}
else
{
return false;
}
}
posType tryNextPos(posType curPos, int i)
{
switch (i)
{
case 1:
curPos.row++;//下
break;
case 2:
curPos.col++;//右
break;
case 3:
curPos.row--;//上
break;
case 4:
curPos.col--;//左
break;
}
return curPos;
}
/*对于第一个格子,先push,(第一个格子元素一定是1,一定走得通)然后通过对第一个格子push pop来确定第一个格子的dir(确定的过程是将(sElemType类型的)e入栈出栈)
*然后默认往下尝试,如果第一个格子往下是1(第一个格子就真正成功入栈了),说明尝试成功。对于每个格子,他想入栈不但自己要是1,而且他周围要有路可走他才能真正入栈
*但假如第一个格子往下尝试不成功,第一个格子就被pop出来修改dir,然后再push进去用havepass判断尝试是否成功
*/
int mazePath(posType start, posType end)
{
sqStack s;
posType curPos;
SElemType e;
int curStep;
initStack(s);
curPos = start;//把当前位置设为start
curStep = 1;//当前步数为1
cout << "begin:" << "(" << start.row << "," << start.col << ")" << endl;
do
{
if (havePass(curPos))//如果当前位置走得通(当前位置是1)
{
makeFootPrint(curPos, curStep);
cout<<"Step"<<curStep<<":"<<"(" << curPos.row << "," << curPos.col << ")" << endl;
e.num = curStep;
e.dir = 1;//默认是先往下尝试
e.coordinate = curPos;
push(s, e);//第一二三。。。个格子入栈
if (curPos.row == end.row && curPos.col == end.col)//是否到终点
{
cout << "Finished!" << endl;
return 1;
}
curPos = tryNextPos(curPos, 1);//刚刚进栈的这个格子尝试(默认)往下走
curStep++;//直接+1
//cout << "step" << curStep<<":";
}
else
{
if (!isEmpty(s))
{
pop(s, e);//一进else就被pop出来,如果e的dir==4,那栈就会连pop两个(因为直接进while)。e在这里更新为不合规的节点,在while里变成不合规节点的前一个节点
while (!isEmpty(s) && e.dir == 4)//某一个格子四个方向都没有路走
{
markPrint(e.coordinate);//就对这个格子做一个标记(把它也改成0)
pop(s, e);//e是这个被pop出来的元素, 某个格子向四周尝试,该格子不断的被push,pop, 直到尝试到一个确定的方向,才会把该方向的新格子push进栈
curStep--;//curStep是push一个元素开始尝试它的第一个dir的时候已经+1了,当尝试了四个方向都不行才减1
cout << "Back to:" << "(" << e.coordinate.row << "," << e.coordinate.col << ")" << endl;
}
if (e.dir < 4)//pop出来修改e.dir,再push进去
{
e.dir++;
push(s, e);
curPos = tryNextPos(e.coordinate, e.dir);//当前位置只能在这修改
}
}
}
} while (!isEmpty(s));
cout << "No path found!" << endl;
return 0;
}
int main()
{
PrintMaze();
posType start, end;
start.row = 1;
start.col = 1;
end.row = 8;
end.col = 8;
if (mazePath(start, end))
{
mazeMap[1][1] = 1;
PrintMaze();
}
return 0;
}
数据结构第三章设计作业(栈实现迷宫求解)
最新推荐文章于 2022-03-18 13:54:16 发布