C语言--------关于迷宫问题的浅析

首先我们先来说说迷宫问题------

迷宫可分为三种情况:简单迷宫、多出口的迷宫、循环迷宫

可以分为这三种简单情况,第一种我们只需用利用栈来实现即可;就是将数据的坐标入栈,当探测上下左右都无路可走的时候,利用回溯来探测别的可走的路,我们可以将第一种和第二种归结为一种情况来看

下面是代码的实现:

#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;
}

猜你喜欢

转载自blog.csdn.net/Sherlock_Provence/article/details/86648245