mfcheer

迷宫问题 192132-01

版权声明:转载请注明出处。 https://blog.csdn.net/u014427196/article/details/44258487

迷宫问题

以一个 m*n 的长方阵表示迷宫, 0 和 1 分别表示迷宫中的通路和障碍。设计一个程序,对任意设定的迷宫,求出一条从入口到出口的通路,或得出没有通路的结论。

要求:

( 1 )首先实现一个以链表作存储结构的栈类型,然后编写一个求解迷宫的非递归程序。求得的通路以三元组 (i,j,d) 的形式输出,其中 (i,j) 指示迷宫中的一个坐标, d 表示走到下一坐标的方向。

( 2 )测试几组数据,数据的规模由小变大,即网格越来越小,障碍越来越复杂。

( 3 ) 实现该问题的可视化界面。

#include<stdio.h>     
#include<iostream>     
#include<math.h>     
#include<stdlib.h>     
#include<ctype.h>     
#include<algorithm>     
#include<vector>     
#include<string.h>     
#include<stack>     
#include<set>     
#include<map>     
#include<sstream>     
#include<time.h>     
#include<utility>     
#include<malloc.h>     
#include<stdexcept>     
#include<iomanip>     
#include<iterator>     

using namespace std;  

int n, m, sx, sy, ex, ey, t;  
int p[110][110];  
char MAP[110][110];
int vis[110][110];  
int dir[4][2] = { { 1, 0 }, { -1, 0 }, { 0, 1 }, { 0, -1 } };  

struct node  
{  
	int x;  
	int y;  
};  

struct node pre[30][30];//存储节点前一个位置   


//////////////////////////  栈   
#define DataType node                  

struct Node;                         
typedef struct Node *PNode;           

typedef struct Node                   
{  
	DataType info;                  
	PNode link;                     
}Node;  

typedef struct LinkStack             
{  
	PNode top;          
}LinkStack;  

typedef struct LinkStack * PLinkStack;     
PLinkStack createEmptyStack(void);  
int isEmptyStack(PLinkStack stack);  
int push(PLinkStack stack, DataType x);  
int pop(PLinkStack stack);  
DataType getTop(PLinkStack stack);  
void showStack(PLinkStack stack);  
void setEmpty(PLinkStack stack);  
void destroyStack(PLinkStack stack);  

PLinkStack createEmptyStack(void)  
{  
	PLinkStack stack = (PLinkStack)malloc(sizeof(struct LinkStack));  
	if (stack == NULL)  
		printf("存储分配失败,请重建栈!\n");  
	else  
		stack->top = NULL;  
	return stack;  
}  

int isEmptyStack(PLinkStack stack)  
{  
	return (stack->top == NULL);  
}  

int push(PLinkStack stack, DataType x)  
{  
	PNode p = (PNode)malloc(sizeof(struct Node));  
	if (p == NULL)  
	{  
		printf("新结点分配内存失败,进栈失败,请重试!\n");  
		return 0;  
	}  
	else  
	{  
		p->info = x;  
		p->link = stack->top;       
		stack->top = p;  
		return 1;  
	}  
}  

int pop(PLinkStack stack)  
{  
	if (isEmptyStack(stack))  
	{  
		printf("栈为空!\n");  
		return 0;  
	}  
	else  
	{  
		PNode p;  
		p = stack->top;   //删除最后一个结点     
		stack->top = stack->top->link;  
		free(p);  
		return 1;  
	}  
}  

DataType getTop(PLinkStack stack)  
{  
	if (isEmptyStack(stack))  
	{  
		printf("栈为空!取栈顶元素失败!\n");  
	}  
	return (stack->top->info);  
}  

void showStack(PLinkStack stack)  
{  
	if (isEmptyStack(stack))  
		printf("当前栈为空!无内容可显示。\n");  
	else  
	{  
		PNode p;  
		p = stack->top;  
		printf("顶--> ");  
		while (p->link != NULL)  
		{  
			printf("%d ", p->info);  
			p = p->link;  
		}  
		printf("%d ", p->info);     
		printf("-->底\n");  
	}  
}  

void setEmpty(PLinkStack stack)  
{  
	stack->top = NULL;  
}  

void destroyStack(PLinkStack stack)  
{  
	if (stack)  
	{  
		stack->top = NULL;  
		free(stack);  
	}  
}  
///////////////////////////   

int check(int x, int y)  
{  
	if (x >= 0 && x < m && y >= 0 && y < n)  
		return 1;  
	return 0;  
}  

void printf_path()  
{  
	node ss,sss;  

	DataType data;  
	PLinkStack stack;  

	stack = createEmptyStack();  

	ss.x = ex;  
	ss.y = ey;  

	while (1)  
	{  
		push(stack, ss);  
		if (ss.x == sx && ss.y == sy)  
			break;  
		ss = pre[ss.x][ss.y];  
	}  

	int pres, presy;  
	printf ("           行走路径 文字描述如下:\n\n\n");
	while (!(isEmptyStack(stack)))  
	{  
		ss = getTop(stack);  
		pop(stack);  
		MAP[ss.x+1][ss.y+1] = '*';
		if (!(isEmptyStack(stack)))  
			sss = getTop(stack);  
		printf("           ");printf("此刻坐标(%d, %d)  ", ss.x, ss.y);  

		if (!(isEmptyStack(stack)))  
		{  
			if (sss.x == ss.x && sss.y == ss.y + 1)  
					printf("向右走\n"); 
			if (sss.x == ss.x && sss.y == sss.y - 1)  
					printf("向左走\n");  
					
			if (sss.x == ss.x + 1 && sss.y == sss.y)  
					printf("向下走\n");
			if (sss.x == ss.x - 1 && sss.y == sss.y)  
					printf("向上走\n"); 
		}  
	}printf("到达终点!\n\n\n\n");  
	printf ("           行走路径图如下:\n");
	
	for(int i=0;i<=m+1;i++)
	{
		printf("           ");
		for(int j=0;j<=n+1;j++)
		{
			if (j==0 || j== n+1)
				printf("| ");
			else if (i == 0 || i == m+1)
				printf("—");
			else 
				printf("%c ",MAP[i][j]);
		}
		printf("\n");
	}
}  

////////////////////////队列   

#define Error( str )        FatalError( str )   
#define FatalError( str )   fprintf( stderr, "%s\n", str ), exit( 1 )   
#define  ElementType node   

#define MAXQUEUE 100   

typedef struct NODE  
{  
	ElementType data;  
	struct NODE* nextNode;  
} NODE;  
typedef struct queue  
{  
	NODE* front;    // 对首指针   
	NODE* rear;     // 队尾指针   
	int items;      // 队列中项目个数   

} *ptrQueue;  
typedef ptrQueue Queue;  
int IsEmpty(Queue q);  
int IsFull(Queue q);  
Queue CreateQueue(void);  
void DisposeQueue(Queue q);  
void MakeEmpty(Queue q);  
void Enqueue(ElementType x, Queue q);  
ElementType Front(Queue q);  
void Dequeue(Queue q);  

int IsFull(Queue q)  
{  
	return q->items == MAXQUEUE;  
}  

int IsEmpty(Queue q)  
{  
	return q->items == 0;  
}  
Queue CreateQueue(void)  
{  
	Queue q;  

	q = (Queue)malloc(sizeof(struct NODE));  
	if (NULL == q)  
		Error("空间不足,队列内存分配失败!");  

	q->front = (NODE*)malloc(sizeof(NODE));  
	if (NULL == q->front)  
		Error("空间不足,队列首节点内存分配失败!");  

	q->rear = (NODE*)malloc(sizeof(NODE));  
	if (NULL == q->rear)  
		Error("空间不足,队列尾节点内存分配失败!");  

	q->items = 0;  

	return q;  
}  

void DisposeQueue(Queue q)  
{  
	MakeEmpty(q);  
	free(q);  
}  

void MakeEmpty(Queue q)  
{  
	if (q == NULL)  
		Error("必须先使用CreateQueue创建队列!");  

	while (IsEmpty(q))  
		Dequeue(q);  
}  

void Enqueue(ElementType x, Queue q)  
{  
	if (IsFull(q))  
		Error("队列已满!");  

	NODE* pnode;  
	pnode = (NODE*)malloc(sizeof(NODE));  
	if (NULL == pnode)  
		Error("新节点分配内存失败!");  

	pnode->data = x;  
	pnode->nextNode = NULL;  
	if (IsEmpty(q))  
		q->front = pnode;           // 项目位于首端   
	else  
		q->rear->nextNode = pnode;  // 链接到队列尾端   
	q->rear = pnode;                    // 记录队列尾端的位置   
	q->items++;                     // 项目数加1   

	return;  
}  

void Dequeue(Queue q)  
{  
	if (IsEmpty(q))  
		Error("队列本身为空!");  

	NODE* pnode;  
	pnode = q->front;  
	q->front = q->front->nextNode;  
	free(pnode);  

	q->items--;  
	if (q->items == 0)  
		q->rear = NULL;  

	return;  
}  

ElementType Front(Queue q)  
{  
	if (!IsEmpty(q))  
		return q->front->data;  
	Error("队列为空\n");  
}  

ElementType FrontAndDequeue(Queue q)  
{  
	ElementType x;  

	if (IsEmpty(q))  
		Error("队列为空!");  
	else  
	{  
		q->items--;  
		x = q->front->data;  
		q->front = q->front->nextNode;  
	}  

	return x;  
}  

///////////////////////   

int bfs()  
{  
	memset(vis, 0, sizeof(vis));  

	Queue sqQueue;  
	sqQueue = CreateQueue();  

	node qq, qqq;  

	qq.x = sx;  
	qq.y = sy;  
	vis[sx][sy] = 1;  

	Enqueue(qq, sqQueue);  

	while (!IsEmpty(sqQueue))  
	{  
		qq = Front(sqQueue);  
		Dequeue(sqQueue);  

		if (qq.x == ex && qq.y == ey)  
		{  
			printf_path();  
			return 1;  
		}  

		for (int i = 0; i < 4; i++)  
		{  
			int x = qq.x + dir[i][0];  
			int y = qq.y + dir[i][1];  

			if (!check(x, y) || vis[x][y] || p[x][y] == 1)  
				continue;  

			qqq = qq;  
			qqq.x = x;  
			qqq.y = y;  

			pre[qqq.x][qqq.y] = qq;  

			vis[x][y] = 1;  
			Enqueue(qqq, sqQueue);  
		}  
	}  
	return 0;  
}  


int main()  
{  
	printf("请输入迷宫长和宽\n");  
	while (cin >> m >> n)  
	{  
		printf("输入起点坐标和终点坐标\n");  
		scanf("%d%d%d%d",&sx,&sy,&ex,&ey);  
		printf("请输入迷宫\n");  
		for (int i = 0; i < m; i++)  
		{  
			for (int j = 0; j < n; j++)  
			{  
				cin >> p[i][j];  
				MAP[i+1][j+1] = p[i][j] + '0';
			}  
		}  
		int ans = bfs();  
		if (ans == 0)  
			printf("不存在起点到终点的通路\n\n\n\n");  
		printf("\n\n\n\n");  
		printf("是否继续 1.yes 2.no\n ");  
		scanf("%d",&t);  
		if (t == 2) { printf("          再见   ,谢谢使用本系统!\n\n\n"); return 0; }  
		printf("\n\n\n\n");  
		printf("请输入迷宫长和宽\n");  
	}  
	return 0;  
}  

测试数据:

5 5
0 0 4 4
0 1 0 0 0
0 1 0 1 0
0 0 0 0 0
0 1 1 1 1
0 0 0 1 0

1
5 5
0 0 4 4
0 1 0 0 0
0 1 0 1 0
0 0 0 0 0
0 1 1 1 0
0 0 0 1 0

2

← 全部文章

留言