图模型的深度优先遍历

问题描述:

如何对于一个图,将其中的结点全部遍历且所有结点仅访问一次?

这个问题和图的深度优先遍历存在一点不同,在图的深度优先遍历中,会在每个结点中挑选一个分支不断的向下,达到最后一个子结点后返回,进入到上一个结点的其他结点中去,如果其他结点已经被访问过了(visited),那么就继续遍历该结点的其他结点,以此类推,不断向上......最终回到根节点。

这里采用回溯的方法来解决这个问题(遍历所有的结点,且每个结点只访问一遍):

1、对于图的每一个节点V,具有n个分支,即该节点和其余的n个结点相连接;

2、从每个节点一层一层的深入,如果到达了重复节点就回归到上一个结点重新来过,如果上一个结点没有可以继续进行探索的结点了,则返回到上上个结点,以此类推;

3、如果该图不能够一次性的遍历所有的结点,则我们设置的条件n==4就无法满足,因此没有这样的通路时就没法输出正确的路径,算法结束(也需要全部遍历结点才能知晓有无这样的路径)

3、我们需要三个数组:

1)一个二维数组,用来存放图模型

2)一个visited一维数组,用来存放已经访问过的结点

3)一个b数组,用来表示图模型遍历的顺序,不同的访问顺序可以通过该数组进行保存并输出

4、使用回溯方法,其实也是暴力求解方法,如果要求所有的解,需要将全部的路径都遍历一遍,但是和两层的for循环的遍历要略微提升一些速度,因为有限制的判断条件,使得从当前结点不会达到一些很明显不会达到的结点中去。

代码:

#include<iostream>
#include<algorithm>
#include<stack>
using namespace std;

//深度优先搜索

//显示
void display(int *b) {
	for (int i = 0; i < 4; i++) {
		cout << b[i] << " ";
	}
	cout << endl;
}

int deepSearch(int a[][5], int *b, int n, int *visited) {
	if (n == 4) {
		display(b);
		return 0;
	}
	if (b[n] != -1) {
		return 0;
	}
	int flag = 1;
	for (int i = 0; i < 5; i++) {
		if (a[n][i] != 0 && visited[i]==0) {//两个点之间有通路,且对应结点还没被访问过
			if (flag == 1) {
				b[n] = i;
				visited[i] = 1;	
				int index = deepSearch(a, b, n + 1, visited);
				if (!index) {
					b[n] = -1;
					visited[i] = 0;//回溯
				}
			}
		}
	}
	return 0;
}

int main() {
	int a[5][5] = {
		{ 0,1,0,0,1 },
		{ 1,0,1,1,1 },
		{ 0,1,0,1,0 },
		{ 0,1,1,0,1 },
		{ 1,1,0,1,0 }
	};
	int b[4] = { -1,-1,-1,-1 };
	int visited[5] = { 1,0,0,0,0 };
	deepSearch(a, b, 0, visited);
	system("pause");
	return 0;
}

运行结果:

(起始结点为0,在每个路径的起始,未显示出来)

发布了13 篇原创文章 · 获赞 0 · 访问量 750

猜你喜欢

转载自blog.csdn.net/zxs0222/article/details/102501553