数据结构之迷宫求解栈(链式栈)实现,队列(循环队列)实现

思路:
将迷宫的布局的矩阵(对应位置的值为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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值