首先我们先来说说迷宫问题------
迷宫可分为三种情况:简单迷宫、多出口的迷宫、循环迷宫
可以分为这三种简单情况,第一种我们只需用利用栈来实现即可;就是将数据的坐标入栈,当探测上下左右都无路可走的时候,利用回溯来探测别的可走的路,我们可以将第一种和第二种归结为一种情况来看
下面是代码的实现:
#include"mig.h"
//int CheckAccess(Pos next)
//{
// if (next._col >= 0 && next._col < N
// &&next._row >= 0 && next._row < N
// &&maze[next._row][next._col] == 1)
// {
// return 1;
// }
// else
// {
// return 0;
// }
//}
//Stack minpath;
//int pathsize = 0;
//int GetMazePath(Pos entry, Pos exit)
//{
// Stack path;
// StackInit(&path);
// StackPush(&path, entry);
// while (StackEmpty(&path))
// {
// Pos cur = StackTop(&path);
// Pos next;
// maze[cur._row][cur._col] = 2;
// if (cur._col == 5)
// {
// if (pathsize == 0 || StackSize(&path) < pathsize)
// {
// pathsize = StackSize(&path);
// }
// }
// next = cur;
// next._row -= 1;
// if (CheckAccess(next))
// {
// StackPush(&path, next);
// continue;
// }
// next = cur;
// next._row -= 1;
// if (CheckAccess(next))
// {
// StackPush(&path, next);
// continue;
//
// }
// next = cur;
// next._row += 1;
// if (CheckAccess(next))
// {
// StackPush(&path, next);
// continue;
// }
// next = cur;
// next._col += 1;
// if (CheckAccess(next))
// {
// StackPush(&path, next);
// continue;
// }
// next = cur;
// next._col -= 1;
// if (CheckAccess(next))
// {
// StackPush(&path, next);
// continue;
// }
// StackPop(&path);
// }
// return 0;
//}
//void PrintMaze()
//{
// size_t i, j;
// for (i = 0;i < N;i++)
// {
// for (j = 0;j < N;j++)
// {
// printf("%d", maze[i][j]);
// }
// printf("\n");
// }
//}
//void TestMaze()
//{
// Pos entry, exit;
// entry._row = 5;
// entry._col = 2;
// exit._row = 3;
// exit._col = 5;
// PrintMaze();
// printf("是否又出口:%d\n", GetMazePath(entry, exit));
// printf("最短路径:%d\n", pathsize);
// PrintMaze();
//
//}
将走过的路标记为2,这样就可以看出走过没走,然后进行探测。
但是第三种就不可以这样,
红色为第一次走的路;蓝色为回溯之后;可以看到循环的部分在第一次回溯的时候已经走过了。这样就不能再走了,这样子就不能正确的实现,当然有问题就有解决问题的办法,我们可以将走过的路一次次递增的去标记,你可以走标记比你大非一的数,因为比你大一就是你刚走过的地方,
可以看出来回溯到4位置之后你可以继续向着11那个方向走,因为11比4大的不止是1,现在我们来看看代码的实现
int CheckAccess(Pos cur,Pos next)
{
if (next._col >= 0 && next._col < N
&&next._row >= 0 && next._row < N
&&maze[next._row][next._col] == 1
||maze[next._row][next._col]>maze[cur._row][cur._col]+1)
{
return 1;
}
else
{
return 0;
}
}
Stack minpath;
int pathsize = 0;
int GetMazePath(Pos entry, Pos exit)
{
Stack path;
StackInit(&path);
StackPush(&path, entry);
maze[entry._row][entry._col] = 2;
while (StackEmpty(&path))
{
Pos cur = StackTop(&path);
Pos next;
if (cur._col == 5)
{
if (pathsize == 0 || StackSize(&path) < pathsize)
{
pathsize = StackSize(&path);
}
}
next = cur;
next._row -= 1;
if (CheckAccess(cur,next))
{
maze[next._row][next._col] = maze[cur._row][cur._col] + 1;
StackPush(&path, next);
continue;
}
next = cur;
next._row -= 1;
if (CheckAccess(cur,next))
{
maze[next._row][next._col] = maze[cur._row][cur._col] + 1;
StackPush(&path, next);
continue;
}
next = cur;
next._row += 1;
if (CheckAccess(cur,next))
{
maze[next._row][next._col] = maze[cur._row][cur._col] + 1;
StackPush(&path, next);
continue;
}
next = cur;
next._col += 1;
if (CheckAccess(cur,next))
{
maze[next._row][next._col] = maze[cur._row][cur._col] + 1;
StackPush(&path, next);
continue;
}
next = cur;
next._col -= 1;
if (CheckAccess(cur,next))
{
maze[next._row][next._col] = maze[cur._row][cur._col] + 1;
StackPush(&path, next);
continue;
}
StackPop(&path);
}
return 0;
}
void PrintMaze()
{
size_t i, j;
for (i = 0;i < N;i++)
{
for (j = 0;j < N;j++)
{
printf("%d", maze[i][j]);
}
printf("\n");
}
}
void TestMaze()
{
Pos entry, exit;
entry._row = 5;
entry._col = 2;
exit._row = 3;
exit._col = 5;
PrintMaze();
printf("是否又出口:%d\n", GetMazePath(entry, exit));
printf("最短路径:%d\n", pathsize);
PrintMaze();
}
void main()
{
TestMaze();
}
下面附上相关栈的实现代码(Stack)
#pragma once
#include <stdio.h>
#include <malloc.h>
#include <assert.h>
#include <stdlib.h>
//typedef int DataType;
#define N 10
//typedef struct Stack
//{
// DataType _a[N];
// int _top;
// 栈顶
//}Stack;
typedef struct Pos
{
int _row;
int _col;
}Pos;
typedef Pos DataType;
typedef struct Stack
{
DataType* _a;
int _top;// 栈顶
int _capacity; // 容量
}Stack;
void StackInit(Stack* ps);
void StackDestory(Stack* ps);
void StackPush(Stack* ps, DataType x);
void StackPop(Stack* ps);
DataType StackTop(Stack* ps);
int StackEmpty(Stack* ps);
int StackSize(Stack* ps);
void StackPrint(Stack * ps);
void TestStack();
//
下面是Stack.c文件的代码
#include"Stack.h"
void StackInit(Stack*ps)
{
assert(ps);
ps->_a = (DataType*)malloc(sizeof(DataType));
assert(ps->_a);
ps->_top = 0;
ps->_capacity = 1;
}
void StackDestory(Stack*ps)
{
assert(ps);
if (ps->_a)
{
free(ps->_a);
ps->_a = NULL;
ps->_top = 0;
ps->_capacity = 0;
}
}
void StackPush(Stack* ps, DataType x)
{
assert(ps);
if (ps->_top == ps->_capacity)
{
ps->_a = realloc(ps->_a, 2 * ps->_capacity * sizeof(DataType));
ps->_capacity *= 2;
}
ps->_a[ps->_top] = x;
ps->_top++;
}
void StackPop(Stack* ps)
{
assert(ps->_a);
assert(ps->_top > 0);
ps->_top--;
}
DataType StackTop(Stack* ps)
{
assert(ps->_a&&ps->_top > -1);
return ps->_a[ps->_top - 1];
}
int StackEmpty(Stack*ps)
{
assert(ps);
return ps->_top == 0 ? 0 : 1;
}
void StackPrint(Stack*ps)
{
int i;
if (ps->_top == 0)
{
printf("栈为空,无法打印\n");
return;
}
printf("栈的内容:");
for (i = ps->_top - 1;i >= 0;i--)
{
printf("%d", ps->_a[i]);
}
printf("\n");
}
int StackSize(Stack*ps)
{
return ps->_top;
}