以栈解决迷宫问题

怎么找到一个迷宫的出口呢。首先要知道迷宫长啥样,之后知道出入口,再之后就是找通路的过程了。

显然主要的部分是如何找通路。我们就举一个例子:

在这个迷宫中0就是墙,1就是路。那么我们可以用一个二维数组来表示这个迷宫。之后我们需要一种结构来实现我们表示位置的移动。

struct Pos
{
	size_t line;
	size_t row;
};

这个结构体通过记录行和列来表示现在处在迷宫的哪个位置。

现在就可以开始进行找通路的过程了。我们很容易想到通过试探当前位置的周围四个或三个位置来找到下一个应该去的位置,直到走到出口就算任务完成了。但是我们在试探的过程中,走到了下个位置,一定要把之前的位置做一个标记,否则我们的程序会一直在两个位置之间走来走去。我们这里通过把之前的位置置为2来防止它走来走去。

                if (pos.row>0 && maze[pos.line * 10 + pos.row - 1] == 1)//左
		{
			p.push(pos.line * 10 + pos.row);
			pos.row--;
			maze[(pos.line * 10 + pos.row)] = 2;
		}
		else if (pos.row < 9 && maze[pos.line * 10 + pos.row + 1] == 1)//右
		{
			p.push(pos.line * 10 + pos.row);
			pos.row++;
			maze[(pos.line * 10 + pos.row)] = 2;
		}
		else if (pos.line > 0 && maze[(pos.line - 1) * 10 + pos.row] == 1)//上
		{
			p.push(pos.line * 10 + pos.row);
			pos.line--;
			maze[(pos.line * 10 + pos.row)] = 2;
		}
		else if (pos.line < 9 && maze[(pos.line + 1) * 10 + pos.row] == 1)//下
		{
			p.push(pos.line * 10 + pos.row);
			pos.line++;
			maze[(pos.line * 10 + pos.row)] = 2;
		}

这段代码就是对上下左右四个方向进行试探的过程,其中我们用一个栈记录下了我们走过的位置,因为迷宫里面有岔路,所以我们走错时需要进行回溯。而选用栈是因为栈的后进先出的特性。说到走进岔路进行回溯,当我们发现上面四种试探完成却没有通路时,就是我们已经走到了死胡同的最深处,需要进行回溯了,那末回溯的过程就是进行拿取栈顶元素,之后出栈的过程。

                        maze[(pos.line * 10 + pos.row)] = 3;
			pos.line = p.top() / 10;
			pos.row = p.top() - pos.line*10;
			p.pop();

上面的代码就是进行回溯的过程,再加一个是否到达终点的判断就完成了主要部分。

                if (pos.line * 10 + pos.row == 91)
		{
			PrintMaze(maze);
			return 1;
		}

上面就是找路径的过程,也就是我们代码的主要逻辑部分。剩下的就是一些注意事项。

读迷宫图我是通过文件指针,fopen,fgets,fclose来实现的。之后在创建了一个二维数组之后我们给函数传参的时候需要把它转换成一个一级指针来传递。我们操作就把它当作一个一维数组来处理。因为在内存中一维数组和二维数组是一样的,只不过表示方式不一样而已,我们这个迷宫通过二维数组表示比较直观,但是用一维数组一样可以处理。

下面是完整的代码和运行的结果。

结果:

可以看到上面的是最初的迷宫,经过我们走迷宫的过程,将走过的岔路标记为了3,正确的通路标记为了2。

完整代码:

#define _CRT_SECURE_NO_WARNINGS 1

#include<iostream>
#include<assert.h>
#include<stack>
using namespace std;

struct Pos
{
	size_t line;
	size_t row;
};

void InitMaze(int *maze)
{
	FILE *p = fopen("maze.txt", "r");
	for (int i = 0; i < 10; i++)
	{
		for (int j = 0; j < 10;)
		{
			int tmp =(int)(fgetc(p))-‘0‘;
			if (tmp == 0)
				maze[i*10+j] = 0;

			if (tmp == 1)
				maze[i*10+j] = 1;

			if (tmp == 1 || tmp == 0)
				j++;
		}
	}

	fclose(p);
}

void PrintMaze(int *maze)
{
	for (int i = 0; i < 10; i++)
	{
		for (int j = 0; j < 10; j++)
		{
			cout << maze[i * 10 + j] << " ";
		}
		cout << endl;
	}
	cout << endl;
}

int GoMaze(int *maze,Pos start)
{
	assert(maze);
	stack<int> p;

	Pos pos;
	pos.line = start.line;
	pos.row = start.row;

	while (1)
	{
		maze[(pos.line * 10 + pos.row)] = 2;

		if (pos.row>0 && maze[pos.line * 10 + pos.row - 1] == 1)//左
		{
			p.push(pos.line * 10 + pos.row);
			pos.row--;
			maze[(pos.line * 10 + pos.row)] = 2;
		}
		else if (pos.row < 9 && maze[pos.line * 10 + pos.row + 1] == 1)//右
		{
			p.push(pos.line * 10 + pos.row);
			pos.row++;
			maze[(pos.line * 10 + pos.row)] = 2;
		}
		else if (pos.line > 0 && maze[(pos.line - 1) * 10 + pos.row] == 1)//上
		{
			p.push(pos.line * 10 + pos.row);
			pos.line--;
			maze[(pos.line * 10 + pos.row)] = 2;
		}
		else if (pos.line < 9 && maze[(pos.line + 1) * 10 + pos.row] == 1)//下
		{
			p.push(pos.line * 10 + pos.row);
			pos.line++;
			maze[(pos.line * 10 + pos.row)] = 2;
		}
		else
		{
			maze[(pos.line * 10 + pos.row)] = 3;
			pos.line = p.top() / 10;
			pos.row = p.top() - pos.line*10;
			p.pop();
		}

		if (pos.line * 10 + pos.row == 91)
		{
			PrintMaze(maze);
			return 1;
		}
	}
}

void Mazetest()
{
	int maze[10][10];
	Pos p;
	p.line = 2;
	p.row = 0;
	InitMaze((int *)maze);
	PrintMaze((int *)maze);
	GoMaze((int *)maze,p);
}

int main()
{
	Mazetest();
	return 0;
}
时间: 2024-12-17 23:50:15

以栈解决迷宫问题的相关文章

用栈实现迷宫游戏寻路

在我们学习数据结构的时候都曾经见过迷宫游戏,迷宫游戏的实现其实并不难,但是,我们在实现每一个算法的时候都应该想一想这个问题的每一个解.最近,博主已经开始重温数据结构啦,记得我们以前学习这里的时候,老师会用队列来实现迷宫最优解的寻找,氮素呢,博主就是这么可爱,博主就是想试试用栈来找一下. 在实现之前让我们先来复习一下栈的特点:first in last out 对于栈这种数据结构我们只能在栈顶对其操作,根据实际情况可将其实现成链式或者顺序结构.但是一般情况下我们都会实现成顺序结构,因为栈的特点导致

数据结构应用:利用栈破解迷宫游戏

最近刚开始学数据结构,发现数据结构真是个神奇的东西哈,很多现实中的问题都可以用不同的数据结 构来解决,比如利用和栈中缀表达式编写一个计算机程序,利用栈破解迷宫游戏,今天我就来跟大家分 享一下如何利用栈来破解迷宫游戏. 学过数据结构的人都知道,栈的特点是:后进先出(First In Last Out);也就是说只能在栈的尾部进 行压栈和出栈,而且出栈的时候只能从最后一个数据开始.如下图: 而我们在破解迷宫游戏的时候采用的方法是"回溯",也就是在寻找通路的时候,每找到一个通路,就将这个数据

用栈解决Largest Rectangle问题

一问题描述 Given n non-negative integers representing the histogram's bar height where the width of each bar is 1, find the area of largest rectangle in the histogram. Above is a histogram where width of each bar is 1, given height = [2,1,5,6,2,3]. The la

C语言 解决迷宫问题练习

利用C语言来解决类似迷宫的问题,下面例子分别用两种方法来解决! [Problem] There is a maze as shown in the diagram below. In the maze in the form of a 100*100 matrix, the white background represents the road while the yellow background represents the wall. Assuming the upper left co

利用数据结构栈求解迷宫问题

本段程序主要利用数据结构栈的先进后出特点,实现回溯求解迷宫路径问题. #include<iostream> #include<stack> using namespace std; //坐标类 struct Point { int x; int y; }; //地图类 template<int A> struct Map { int (*p)[A]; int row;//行数 int col;//列数 }; //start起始点, end终止点 template<

hdu 3666(差分约束,手动栈解决超时问题)

THE MATRIX PROBLEM Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 8016    Accepted Submission(s): 2092 Problem Description You have been given a matrix CN*M, each element E of CN*M is positive

【Java EE 学习第69天】【struts2】【paramsPrepareParamsStack拦截器栈解决model对象和属性赋值冲突问题】

昨天有同学问我问题,他告诉我他的Action中的一个属性明明提供了get/set方法,但是在方法中却获取不到表单中传递过来的值.代码如下(简化后的代码) 1 public class UserAction implements modelDriven<User>(){ 2 private String name; 3 private User model; 4 public void setName(String name){ 5 this.name=name; 6 } 7 public St

利用栈求解迷宫问题

利用栈求解迷宫问题 源代码: #include<stdio.h> #include<stdlib.h> #define M 8 #define N 8 #define MaxSize M*N typedef struct { int i;//当前方块的行号 int j;//当前方块的列号 int di; //di是下一个可走的相邻方块的方位号 }Box; typedef struct { Box data[MaxSize]; int top;      //栈顶指针 }StType

利用栈实现迷宫求解

利用栈实现迷宫求解 前言:众所周知,栈是(First in last out)先进后出的数据结构,利用这个属性可以实现类似与回溯的方式,比如当前数据满足条件,则入栈,否则出栈返回上一级,依次循环. 在本题中,将每个迷宫路径上的点封装成上下左右四个方向数节点,先入栈迷宫入口节点,如果上下左右没被使用,则将其上下左右的点入栈,否则出栈.如果最终达到迷宫终点则成功,否则失败. 如下是每个节点的数据结构 1 typedef struct{ 2 int top; 3 int bottom; 4 int l