利用DFS和BFS解决基本的迷宫问题

利用DFS和BFS解决基本的迷宫问题

思路

首先做出一下规定:

地图用一个二维数组表示,0表示可以通过,1表示不能通过,2表示起点,3表示终点

如何遍历数组中的上下左右四个位置的数?
设置一个标准数组,{1,0},{-1,0},{0,1},{0,-1},设数组为a[n][m] 

for(i=0;i<n;i++)
{
    for(j=0;j<m;j++)
        {
            for(k=0;k<4;k++)
                {
				if (i + direction[k][0] < n && i + direction[k][0] >= 0 && j + direction[k][1] >= 0 && j + direction[k][1] < m)
                        {
                               //a[i + direction[k][0]][j + direction[k][1]] 对这个进行操作即可
                        }
                }
        }
}

首先地图中的一个结点最多有4个邻接结点,先用数组存储地图信息,后将信息进行转置,使得其用图来表达,注意地图中为障碍的结点,我将其规定为没有邻接结点

利用BFS遍历与DFS对图进行遍历即可,我在之前的文章已经写过了(文章链接:利用BFS和DFS实现对无向图的遍历(图的表达方式为邻接矩阵和邻接表)-CSDN博客

 在此我就只介绍如何保存路径的问题?

同:DFS和BFS我都采用了string这个类来存储,在函数中对string类如果有进行修改操作,记得参数写为引用!!!

异:

在DFS中,因为是一个递推的过程,顺序是顺着来的,直接存放就行,同时如何在string中加字符,我是将‘0’+对应的结点的序号转换为一个ASIIIC码对应的字符再进行存入,输出时输出该字符减去‘0’就行

在BFS中采用了递归的思路,函数的返回值为bool型,如果递归到了结果点,则返回true,其余的情况进行||操作,来获得是否已经访问到终点的信息。存储路径的方式与上相同。

补充:
其实并不一定要用string,我现在觉得采用stack(栈)或者队列(queue)会更加简单。(博主写完代码才想起来,感觉绕了一大个圈来存储信息,博主有待进步)

代码

#include<iostream>
#include<string>
#include<queue>
using namespace std;
typedef struct node
{
	int name;
	node* next;
}node;
typedef struct NODE
{
	node* nodedata;
	string path;
}NODE;
class Graph
{
private:
	node* AdjacencyList;
	int num;//表示结点的总个数
	int begin;//迷宫的起点
	int end;//迷宫的终点
public:
	Graph();
	void BFS();
	void DFS();
	bool DFS(string &s,node*NODE,bool*judge);
};
/*在构造函数中实现了迷宫地图的读取,和将迷宫地图转换为图的邻接表的存储方式*/
Graph::Graph()
{	
	int direction[4][2] = { {1,0} ,{-1,0},{0,-1},{0,1} };
	int n, m, i, j, k = 0;
	cout << "输入迷宫地图的宽度" << endl;
	cin >> m;
	cout << "输入迷宫地图的长度" << endl;
	cin >> n;
	this->num = n * m;
	int** map = new int* [n];
	for (i = 0; i < n; i++)
	{
		map[i] = new int[m];
	}
	cout << "地图的详细详细信息" << endl;
	for (i = 0; i < n; i++)
	{
		for (j = 0; j < m; j++)
		{
			cin >> map[i][j];
		}
	}
	AdjacencyList = new node[n * m];
	for (i = 0; i < n * m; i++)
	{
		AdjacencyList[i].next = NULL;
	}
	for (i = 0; i < n; i++)
	{
		for (j = 0; j < m; j++)
		{
			AdjacencyList[i * m + j].name = i * m + j;
			if (map[i][j] == 2)
			{
				begin = i * m + j;
			}
			else if (map[i][j] == 3)
			{
				end = i * m + j;
			}
			for (k = 0; k < 4; k++)
			{
				if (i + direction[k][0] < n && i + direction[k][0] >= 0 && j + direction[k][1] >= 0 && j + direction[k][1] < m&&map[i][j]!=1)
				{
					if (map[i + direction[k][0]][j + direction[k][1]] == 0|| 
						map[i + direction[k][0]][j + direction[k][1]] == 2||
						map[i + direction[k][0]][j + direction[k][1]] == 3)
					{
						node* p = new node;
						p->name = m * (i + direction[k][0]) + j + direction[k][1];
						p->next = AdjacencyList[i * m + j].next;
						AdjacencyList[i * m + j].next = p;
					}
				}
			}
		}
	}
	delete[] map;
}
void Graph::BFS()
{
	cout << "---BFS----" << endl;
	bool* judge = new bool[num];
	for (int i = 0; i < num; i++)
	{
		judge[i] = false;
	}
	queue<NODE*>s;
	judge[begin] = true;
	NODE* head = new NODE;
	head->nodedata = &AdjacencyList[begin];
	char add = AdjacencyList[begin].name + '0';
	head->path += add;
	s.push(head);
	while (!s.empty())
	{
		NODE* P = s.front();
		s.pop();
		node* p = P->nodedata;
		p = p->next;
		while (p != NULL)
		{
			if (judge[p->name] != true)
			{
				judge[p->name] = true;
				NODE* x;
				x = new NODE;
				x->nodedata = &AdjacencyList[p->name];
				char m = p->name + '0';
				x->path += P->path+m;
				if (p->name == end)
				{
					int n = x->path.size(),i;
					for (i = 0; i < n; i++)
					{
						cout << x->path[i] - '0';
						if (i < n - 1)
						{
							cout << "->";
						}
					}
					cout << endl;
					return;
				}
				s.push(x);
			}
			p = p->next;
		}
	}
		cout << "无法到达终点" << endl;
}
void Graph::DFS()
{
	cout << "---DFS----" << endl;
	string s;
	bool* judge = new bool[num];
	for (int i = 0; i < num; i++)
	{
		judge[i] = false;
	}
	judge[begin] = true;
	bool flag = DFS(s,&AdjacencyList[begin],judge);
	if (flag)
	{
		for (int i =s.size()-1; i >=0; i--)
		{
			cout << s[i] - '0';
			if (i > 0)
			{
				cout << "->";
			}
		}
		cout << endl;
	}
	else cout << "无法到达终点" << endl;
}
bool Graph::DFS(string &s,node*NODE,bool*judge)
{
	if (NODE->name == end)
	{
		char x = NODE->name + '0';
		s += x;
		return true;
	}
	else
	{
		bool flag = false;
		node* p = NODE;
		while (p->next != NULL)
		{
			if (!judge[p->next->name])
			{
				judge[p->next->name] = true;
				flag=DFS(s, &AdjacencyList[p->next->name], judge) || flag;
			}
			p = p->next;
		}
		if (flag)
		{
			char x = NODE->name + '0';
			s += x;
			return true;
		}
		else
		{
			return false;
		}
	}
}
int main()
{
	Graph a;
	a.DFS();
	a.BFS();
	return 0;
}

 总结:

代码有待加强,合理运用了ASSIIC码,个人认为分情况使用栈或者队列来存储会更加简单,这里用string略显麻烦,大家可以自行修改。

  • 16
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值