深度优先和广度优先算法的寻路问题求解

两个算法寻路的基本思路都是首先判断从起点是否能到达目标点,再一步一步从目标点返回到起点,得到路径。

比如要从下面图的0节点到7号节点,首先利用两种算法判断0号是否能到7号,再从7号返回到起点0点。

深度优先和广度优先算法的寻路问题求解_第1张图片

首先简单介绍以下两种算法,这两种图的搜索方法都可以简单地类比为二叉树的遍历算法。

深度优先搜索:类似于树的先序遍历(根节点->左子树的根节点->右子树的根节点),结果为:0(1(378)4)(256)

广度优先搜索:类似于树的层次序遍历(本层的节点->下一层的节点),结果为:012345678

一、建立无向图G

typedef struct {
	int vexnum;//顶点的个数
	AdjMatrix arcs;//图的邻接矩阵
}Graph;

要判断0节点是否能通到7节点,则应采用邻接矩阵,其中的元素用0,1来表示两个节点是否可以直接到达。比如上面的图,0节点可以到1,2节点,则V{0,1}=V{0,2}=1.这样做的目的是让程序知道哪条路是可行的。

二、两种算法都是通过访问矩阵,寻找与本节点相连的未被访问过的节点。

因为本问题要解决的是找出路径,所以在找到下一个节点后,当前节点应该以父节点的名义保存。然后在找到目标节点后,依次向上寻找父节点,以及它的父节点……

typedef struct {
	int current;
	int parent;
}node;

1. 深度优先搜索:

由于在数据量大的情况下,递归算法会造成溢出,所以采用栈来代替递归。即首先把在同一层的节点从右到左压入栈中(比如图中的第二层,首先将2压入栈中,再将1压入栈中,这时第二层与第一层的连通节点(1,2)访问完毕,从栈中弹出一个数,1,再把1的“子树”的第二层从右到左压入栈……一直到栈中没有元素)。这表明很多递归可以通过栈来非递归化。

vector DFS(Graph G, int start, int target)//深度优先
{
	bool visited[MaxVnum]={false};
	stack stk;
	vector DFSvec;
	node temp;
	vector output;
	visited[start] = true; //从V开始访问,flag它
	temp.current = start;
	temp.parent = -1;
	output.push_back(temp);
	for (int j = G.vexnum - 1; j >= 0; j--) {
		if (G.arcs[start][j] == 1 && visited[j] == false) //这里可以获得V未访问过的邻接点
		{
			stk.push(j);
			visited[j] = true;
			temp.parent = start;
			temp.current = j;
			output.push_back(temp);
		}
	}
	while (!stk.empty())
	{
		int temp1 = stk.top();
		//cout << temp1;
		if (temp.current == target) break;
		stk.pop();
		for (int j = G.vexnum - 1; j >= 0; j--) {
			if (G.arcs[temp1][j] == 1 && visited[j] == false) //这里可以获得V未访问过的邻接点
			{
				stk.push(j);
				visited[j] = true;
				temp.parent = temp1;
				temp.current = j;
				output.push_back(temp);
			}

		}
	}
	//寻路
	if(output.size()==1) AfxMessageBox(_T("地图数据不正"));
	else{
	stack result;
	int j;
	for (j = 0;j

2. 广度优先搜索:

与深度优先不同,广度优先是先把同一层的节点遍历完,再去看下一层节点。所以选用队列(同样以图的第二层为例,首先从左到右把1压入队列,再把2压入队列,把1弹出,寻找与1相连接的未访问过的节点,并将其依次压入队列,弹出2……)

vector BFS(Graph G, int start, int target)//广度优先
{

	bool visited[MaxVnum]={false};
	queuetemp;
	vector BFSvec;
	node n;
	vector output;
	visited[start] = true; //从V开始访问,flag它
	n.current = start;
	n.parent = -1;
	output.push_back(n);
	for (int j = 0;j result;
	int j;
	for (j = 0;j

 

你可能感兴趣的:(编程题)