数据结构---对复杂迷宫进行求解(通路间带环)

       我们通常见的迷宫多种多样,在这里以多通路迷宫为例,对迷宫进行求解,找出最短路径,用C语言对其进行编写,涉及到一些操作包括:

       1. 初始化迷宫地图数据 --》2.检测迷宫的入口是否有效 --》 3. 检测当前位置是否为迷宫的出口 --》4. 保存最短路径 --》5. 检测当前位置的下一步是否能够走通 --》6. 走迷宫 --》7. 具体走迷宫方式 --》8. 打印迷宫地图数据 --》9. 打印路径 

      下面用C实现该操作的一些代码:

    maze.c-->下面是用递归的方式找到迷宫中的最短路径

 

#define _CRT_SECURE_NO_WARNINGS 0;
#include "maze.h"
#include "stack.h"
#include <stdio.h>
#include <assert.h>
//初始化迷宫
void MazeInit(maze* s, DataTypeMaze arr[MAZE_ROW][MAZE_COL])
{
	assert(s);
	int i = 0, j = 0;
	for (i = 0; i < MAZE_ROW; i++)
	{
		for (j = 0; j < MAZE_COL; j++)
		{
			s->maze[i][j] = arr[i][j];
		}
	}
}
//打印迷宫
void PrintMaze(maze m)
{
	int i = 0, j = 0;
	for (i = 0; i < MAZE_ROW; i++)
	{
		for (j = 0; j < MAZE_COL; j++)
		{
			printf("%d ", m.maze[i][j]);
		}
		printf("\n");
	}
}
// 检测迷宫的入口是否有效 
int IsValidEnter(maze *m, PosType enter)
{
	 assert(m);
	 if ((enter._x == 0) || (enter._y == 0) || (enter._x == MAZE_ROW - 1) || (enter._y == MAZE_COL - 1))
	 {
		 if (m->maze[enter._x][enter._y] >= 1)
			 return 1;
	 }

	       return 0;
}
// 检测cur位置是否为迷宫的出口 
int IsMazeExit(maze* m, PosType cur, PosType enter)
{
	assert(m);
	if (cur._x == enter._x && cur._y == enter._y)
		return 0;

	if (cur._x == 0 || cur._x == MAZE_COL - 1 || cur._y == 0 || cur._y == MAZE_ROW - 1)
	{
		return 1;
	}

	return 0;
}
// 检测当前位置是否为通路 
int IsPass(maze* m, PosType cur)
{
	assert(m);
	if (m->maze[cur._x][cur._y] == 1)
		return 1;

	return 0;
}
// 打印路径 
void PrintPath(Stack* s)
{
	assert(s);
	printf("over");
	while (!IsEmptyStack(s))
	{
		printf("<- %d,%d ", StackTop(s));
		StackPop(s);
	}
}


// 检测当前位置的下一步是否能够走通 
int IsNextPass(maze* m,PosType cur, PosType next)
{
	assert(m);
	if ((m->maze[next._x][next._y] == 1) || (m->maze[cur._x][cur._y]< m->maze[next._x][next._y]))  
		return 1;

    	return 0;
}

void printPath(Stack Path)
{
	int i = 0;
	for (; i < stackSize(&Path); i++)
	{
		printf("%d,%d-> ", Path.arr[i]);
	}
	printf("over \n");
}
// 保存最短路径 
void SaveShortPath(Stack* path, Stack* shortPath)
{
	assert(path);
	assert(shortPath);
	int i = 0;
	shortPath->_top = 0;
	for (; i < stackSize(path); i++)
	{
       StackPush(shortPath, path->arr[i]);
	}
}
// 走迷宫 
void PassMaze(maze* m, PosType  enter, Stack* ShortPath)
{
	assert(m);
	assert(ShortPath);
	Stack path;
	if (!IsValidEnter(m, enter))
	{
		printf("无效的入口点");
		return;
	}

	StackInit(&path);
	_PassMaze(m, enter, enter,&path,ShortPath);
}
// 复杂迷宫--》具体走迷宫方式 
void _PassMaze(maze *m, PosType enter,PosType cur, Stack *path,Stack* shortPath)
{
	assert(path);
	assert(shortPath);
	PosType next = cur;

	if (cur._x ==enter._x && cur._y == enter._y)
		m->maze[cur._x][cur._y] = 2;

		StackPush(path, cur);
	if (IsMazeExit(m, cur, enter))
	{
			if (shortPath->_top == 0 || stackSize(path)<stackSize(shortPath))
				SaveShortPath(path, shortPath);
		  
			StackPop(path);
			return;
	}

	//上
	next = cur;
	next._x -= 1;
	if (IsNextPass(m, cur, next))
	{
		m->maze[next._x][next._y] = m->maze[cur._x][cur._y] + 1;
		_PassMaze(m,enter, next, path, shortPath);
	}

	//右
	next = cur;
	next._y += 1;
	if (IsNextPass(m, cur, next))
	{
		m->maze[next._x][next._y] = m->maze[cur._x][cur._y] + 1;
		_PassMaze(m, enter, next, path, shortPath);
	}

	//左
	next = cur;
	next._y -= 1;
	if (IsNextPass(m, cur, next))
	{
		m->maze[next._x][next._y] = m->maze[cur._x][cur._y] + 1;
		_PassMaze(m, enter, next, path, shortPath);
	}

	//下
	next = cur;
	next._x += 1;
	if (IsNextPass(m, cur, next))
	{
		m->maze[next._x][next._y] = m->maze[cur._x][cur._y] + 1;
		_PassMaze(m, enter, next, path, shortPath);
	}

	StackPop(path);
}


下面是用测试代码

//多通络带环迷宫
void testMaze()
{
	maze m;
	Stack shortPath;
	StackInit(&shortPath);
	DataType x;
	x._x = 5;
	x._y = 1;
	DataTypeMaze arr[MAZE_ROW][MAZE_COL] = { { 0,0 },{ 0, 1,1,1 },{ 0, 1,0,1 },{ 0, 1, 0, 1},{ 0,1,1,1,1,1 },{ 0, 1} };
	MazeInit(&m, arr);
	PrintMaze(m);
	PassMaze(&m, x, &shortPath);
	printf("迷宫最短路径--:");
	PrintPath(&shortPath);
	printf("**********************\n");
	PrintMaze(m);
}
int main()
{
	testMaze();
	system("pause");
	return 0;
}


    上面就是实现复杂迷宫求解的C代码,下一篇会写用循环和递归两种方式对简单迷宫进行求解!!!


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值