思路:
将迷宫的布局的矩阵(对应位置的值为0:表示通路,1:表示障碍,-1:表示已访问过)作为全局变量,flag作为全局变量,flag=1:邻居中有出口,flag=0:邻居中无出口,然后先把入口Enter的位置入栈,然后把入口在迷宫布局中对应的值改成-1,表示已经访问过,然后进入循环,
{栈顶元素出栈,先判断栈顶元素是否是出口的位置,如果是,则退出循环,如果不是则继续,将flag改成0,然后从出栈元素开始按照一定次序访问邻居,
{如果邻居存在(注意不能越界)且可通(在矩阵中对应位置是0),则将flag改为1,位置入栈,迷宫矩阵中邻居位置所对应的值改为-1}
如果flag=0,就出栈}
#include<stdio.h>
#include<stdlib.h>
#define OVERFLOW -1
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define MAX_ROW 12
#define MAX_COL 14
typedef struct {
int Line; //行
int Column;//列
}SElemType;
typedef int Status;
int flag;
int maze[12][14] = {
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1,
1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1,
1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1,
1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1,
1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1,
1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1,
1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1,
1, 0, 0, 0, 0, 1 ,0 ,0, 0 ,0 ,1 ,0 ,1 ,1,
1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1,
1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
typedef struct {
int flag;
SElemType* base;
SElemType* top;
int stacksize;
}SqStack;
typedef struct SNode {
SElemType data;
struct SNode* next;
}SNode, * LinkStack;
LinkStack InitStack()//注意这个初始化方式!!!!!!
{
LinkStack s = (SNode*)malloc(sizeof(SNode));
if (!s)
exit(OVERFLOW);
s->next= NULL;
return s;
}
void Push(LinkStack s, SElemType e)
{
LinkStack p = (SNode*)malloc(sizeof(SNode));
if (p == NULL)
exit(OVERFLOW);
p->data = e;
p->next = NULL;
p->next = s->next;
s->next = p;//与单链表的头插法相似
}
SElemType Pop(LinkStack s)
{
LinkStack q;
q = s->next;
SElemType e = q->data;
s->next = q->next;
free(q);//删除单链表的第一个元素
return e;
}
Status StackEmpty(LinkStack s)
{
if (s->next == NULL)
return TRUE;
else
{
return FALSE;
}
}
SElemType GetTop(LinkStack l)
{
return l->next->data;
}
void StackTravers(LinkStack s)
{
SNode* p = s->next;
while (p != NULL)
{
printf("(%d,%d)\n",p->data.Line, p->data.Column);
p = p->next;
}
}
void Visit(SElemType e, LinkStack s, int i)
{
Push(s, e);
switch (i)
{
case 1:e.Column++; Push(s, e); maze[e.Line][e.Column] = -1; flag = 1; break;//向右
case 2:e.Line++; Push(s, e); maze[e.Line][e.Column] = -1; flag = 1; break;//向下
case 3:e.Column--; Push(s, e); maze[e.Line][e.Column]= -1; flag = 1; break; //向左
case 4:e.Line--; Push(s, e); maze[e.Line][e.Column]= -1; flag = 1; break;//向上
}
}
Status Mazesolution(int line,int column)
{
SElemType StackTop,Enter,Path;
Enter.Column = 1;
Enter.Line = 1;
maze[1][1] = -1;
LinkStack s=InitStack();
Push(s, Enter);
while (!StackEmpty(s))
{
StackTop = GetTop(s);
if (StackTop.Line == line - 2 && StackTop.Column == column - 2)
{
StackTravers(s);//打印路径
return OK;
}
flag = 0;
if (StackTop.Column + 1 < column - 1 && maze[StackTop.Line][StackTop.Column+1] == 0)//向右
{
Visit(StackTop, s,1);
continue;
}
if (StackTop.Line + 1 < line - 1 && maze[StackTop.Line+1][StackTop.Column] == 0)//向下
{
Visit(StackTop, s, 2);
continue;
}
if (StackTop.Column -1 >=1 && maze[StackTop.Line][StackTop.Column-1] == 0)//向左
{
Visit(StackTop, s, 3);
continue;
}
if (StackTop.Line - 1 >=1 && maze[StackTop.Line-1][StackTop.Column] == 0)//向上
{
Visit(StackTop, s, 4);
continue;
}
if (flag == 0)
{
Path=Pop(s);
}
}
return ERROR;
}
int main()
{
printf("%d\n",Mazesolution(12, 14));
return 0;
}
循环队列: (感觉用队列更简单一点)
入口入队列q,修改入口位置在迷宫矩阵中的值为-1,然后进入循环,只要队不空
{
出队A
如果A是出口, return OK;
{从A开始按一定次序扫描邻居B,如果B的位置不越界且可通,修改位置B在迷宫矩阵中的值为-1,B进队列}
}
#include<stdio.h>
#include<stdlib.h>
#define OVERFLOW -1
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define MAX_ROW 12
#define MAX_COL 14
#define MAXQSIZE 100 //最大队列长度
typedef struct {
int Line; //行
int Column;//列
}QElemType;
typedef int Status;
int flag;
int maze[12][14] = {
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1,
1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1,
1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1,
1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1,
1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1,
1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1,
1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1,
1, 0, 0, 0, 0, 1 ,0 ,0, 0 ,0 ,1 ,0 ,1 ,1,
1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1,
1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
typedef struct {
QElemType* base;//动态分配存储空间
int front;//头指针,若队列不空,指向队列头元素
int rear;//尾指针,若队列不空,指向队列尾元素的下一个位置
}SqQueue;
Status InitQueue(SqQueue* Q)
{
Q->base = (QElemType*)malloc(MAXQSIZE * sizeof(QElemType));
if (!Q->base)
exit(OVERFLOW);
Q->front = Q->rear = 0;
return OK;
}
Status EnQueue(SqQueue* Q, QElemType e)
{
if ((Q->rear + 1) % MAXQSIZE == Q->front)//判满
return ERROR;
Q->base[Q->rear] = e;
Q->rear = (Q->rear + 1) % MAXQSIZE;
return OK;
}
Status Dequeue(SqQueue* q, QElemType* e)
{
if (q->front == q->rear)//判空
return;//队列为空
*e = q->base[q->front];
q->front = (q->front + 1) % MAXQSIZE;
return OK;
}
int QueueLength(SqQueue Q)
{
return (Q.rear - Q.front + MAXQSIZE) % MAXQSIZE;//注意
}
void QueueTravers(SqQueue q)
{
for (int i = 0; i < QueueLength(q); ++i)
{
printf("%d %d\n", q.base[i].Line,q.base[i].Column);
}
}
void Visit(QElemType e, SqQueue* s, int i)
{
EnQueue(s, e);
switch (i)
{
case 1:e.Column++;EnQueue(s, e); maze[e.Line][e.Column] = -1; break;//向右
case 2:e.Line++; EnQueue(s, e); maze[e.Line][e.Column] = -1; break;//向下
case 3:e.Column--; EnQueue(s, e); maze[e.Line][e.Column]= -1; break; //向左
case 4:e.Line--; EnQueue(s, e); maze[e.Line][e.Column]= -1; break;//向上
}
}
Status Mazesolution(int line,int column)
{
QElemType Enter;
QElemType* Path = (QElemType*)malloc(sizeof(QElemType));
Enter.Column = 1;
Enter.Line = 1;
maze[1][1] = -1;
SqQueue* q = (SqQueue*)malloc(sizeof(SqQueue));
int t=InitQueue(q);
EnQueue(q, Enter);
while (q->front!=q->rear)
{
t=Dequeue(q, Path);
printf("%d %d\n", Path->Line, Path->Column);//打印路径?
if (Path->Line == line - 2 && Path->Column == column - 2)
{
return OK;
}
flag = 0;
if (Path->Column + 1 < column - 1 && maze[Path->Line][Path->Column+1] == 0)//向右
{
Visit(*Path, q,1);
continue;
}
if (Path->Line + 1 < line - 1 && maze[Path->Line+1][Path->Column] == 0)//向下
{
Visit(*Path, q, 2);
continue;
}
if (Path->Column -1 >=1 && maze[Path->Line][Path->Column-1] == 0)//向左
{
Visit(*Path, q, 3);
continue;
}
if (Path->Line - 1 >=1 && maze[Path->Line-1][Path->Column] == 0)//向上
{
Visit(*Path, q, 4);
continue;
}
}
return ERROR;
}
int main()
{
printf("%d\n",Mazesolution(12, 14));
return 0;
}