您的位置:首页 > 其它

用栈实现迷宫求解Maze

2017-07-16 17:03 246 查看
今天我参考严蔚敏的《数据结构》第3章 栈和队列的3.2.4上的问题描述、解决思路和伪代码把迷宫求解的问题自己实现了一遍,感觉超开心的哇~~嘻嘻,贴出来,以供以后翻阅。

解决过程中的几点思考:

1.对于position NextPos(position cur, int dir)函数,它的目的不是提供一个可行的下一个位置,而是提供一个下一个要考虑的位置,至于可不可行,暂时不用考虑,可不可行的判断实际上是由MazePath函数里的if (mazeStatus[curPos.x][curPos.y]==1)完成的。所以NextPos函数不用写成下面这样

position nextPos = cur;

int temp;

if (dir == 1)
{
temp = mazeStatus[cur.x+1][cur.y];
if (temp==0||temp==1)
{
nextPos.x++;
}
else
{
dir = 2;
}
}
if (dir == 2)
{
temp = mazeStatus[cur.x][cur.y+1];
if (temp==0||temp==1)
{
nextPos.y++;
}
else
{
dir = 3;
}
}
if (dir==3)
{
temp = mazeStatus[cur.x-1][cur.y];
if (temp == 0 || temp == 1)
{
nextPos.x--;
}
else
{
dir = 4;
}
}
if (dir==4)
{
nextPos.y--;
}

2.关于



中的while为什么不能改成if,是因为我们在每一次pop完之后都要对这个节点进行判断,判断是否已经对其周边的四个位置已经考虑过了,如果周围四个节点都已经考虑过,则废弃当前位置,即mazeStatus[t.pos.x][t.pos.y]=3;如果在这里我们将while改成if,对最终形成的路线不会有影响,但是可能有个别迷宫的最终位置状态有误(0表示未访问过且“此路不通”;1表示位访问过且“此路通”;2表示访问过,且属于线路;3表示访问过,但是不可行)。

正确的结果图:



如果将上述的while改成if的结果图,红圈的地方表示状态有误:



最后附上完整的代码~~
#include
#include

typedef struct position{
int x;
int y;
};
typedef struct{
int ord; //通道块在路径上的序号
position pos;//(x,y)为位置坐标
int di;//指示当前通道块的下一个移动方向
}SElemType;

#define InitStackSize 100
#define StackIncrease 10
position startPos = {1,1};
position endPos = {8,8};
int mazeStatus[10][10] = {
{0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0}
};

typedef struct{
SElemType *base;
SElemType *top;
int stackSize;
}SqStack;

void InitStack(SqStack &S)
{
S.base = (SElemType*)malloc(InitStackSize * sizeof(SElemType));
if (!S.base)
{
exit(-1);
}
S.top = S.base;
S.stackSize = InitStackSize;
}

void Push(SqStack &S, SElemType e)
{
if (S.top-S.base >= S.stackSize)
{
S.base = (SElemType*)realloc(S.base, (S.stackSize + StackIncrease)*sizeof(SElemType));
if (!S.base)
{
exit(-1);
}
S.top = S.base + S.stackSize;
S.stackSize += StackIncrease;
}
*S.top++ = e;
}

int StackEmpty(SqStack S)
{
if (S.base==S.top)
{
return true;
}
else
{
return false;
}
}

void Pop(SqStack &S, SElemType &e)
{
if (!StackEmpty(S))
{
e = *--S.top;
}
}

void GetTop(SqStack S, SElemType &e)
{
if (!StackEmpty(S))
{
e = *(S.top - 1);
}
}

int operator ==(position a, position b)
{
if (a.x==b.x&&a.y==b.y)
{
return 1;
}
return 0;
}
position NextPos(position cur, int dir)
{
position nextPos = cur;
switch (dir)
{
case 1:nextPos.y++; break;
case 2:nextPos.x++; break;
case 3:nextPos.y--; break;
case 4:nextPos.x--; break;
default:
break;
}
return nextPos;
}

void printStack(SqStack S)
{
SElemType e;
std::cout << "----------路径(格式为--步数:(x,y))-----------------" << std::endl;
while (!StackEmpty(S))
{
Pop(S, e);
std::cout << e.ord << ":(" << e.pos.x << "," << e.pos.y << ")" << std::endl;
}
}

int MazePath(int maze[][10], position start, position end)
{
SqStack S;//用于保存路径的栈结构
InitStack(S);
position curPos = start;
int curStep = 1;
do{
if (mazeStatus[curPos.x][curPos.y]==1)//1表示可通且未访问过
{
mazeStatus[curPos.x][curPos.y] = 2;//2访问过
SElemType e = { curStep, curPos, 1 };
Push(S, e);
if (curPos == end)
{
printStack(S);
return true;
}
curPos = NextPos(curPos, 1);
curStep++;
}
else{
if (!StackEmpty(S))
{
SElemType t;
Pop(S, t);
curStep--;
while (t.di==4&&!StackEmpty(S))
{
mazeStatus[t.pos.x][t.pos.y] = 3;//3不可通过
Pop(S, t);
curStep--;
}
if (t.di<4)
{
t.di++;
Push(S, t);
curStep++;
curPos = NextPos(t.pos, t.di);
}
}
}

} while (!StackEmpty(S));
return false;
}

int main()
{
std::cout << "--------初始迷宫---------0表示走不通,1表示走得通--" << std::endl;
for (int i = 0; i < 10; i++)
{
if (i==0)
{
std::cout << "  0 1 2 3 4 5 6 7 8 9" << std::endl;
std::cout << "  - - - - - - - - - -" << std::endl;
}
for (int j = 0; j < 10; j++)
{
if (j==0)
{
std::cout << i << "|";
}
std::cout << mazeStatus[i][j] << " ";
}
std::cout << std::endl;
}
MazePath(mazeStatus, startPos, endPos);
std::cout << "--------结果迷宫----2表示路径----3表示尝试过失败的路线---------" << std::endl;
for (int i = 0; i < 10; i++)
{
if (i == 0)
{
std::cout << "  0 1 2 3 4 5 6 7 8 9" << std::endl;
std::cout << "  - - - - - - - - - -" << std::endl;
}
for (int j = 0; j < 10; j++)
{
if (j == 0)
{
std::cout << i << "|";
}
std::cout << mazeStatus[i][j] << " ";
}
std::cout << std::endl;
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: