Algorithm第四版算法 C++实现(十三)——深度优先搜索(DFS)

本文详细介绍了深度优先搜索(DFS)的基本原理和实现方式,通过C++代码展示了如何使用DFS遍历图并查找路径。此外,还讨论了DFS在图的连通性判断上的应用,对比了DFS与union-find算法的优缺点。DFS作为一种基础且重要的图论算法,广泛应用于各种图相关问题的解决中。
摘要由CSDN通过智能技术生成

深度优先搜索,即DFS(depth first search)是一种图的搜索方法,一般使用递归实现。
深度优先搜索的原理很简单,即从一个点开始,将这点标记为已搜索,然后找到与该点链接的顶点,再在该顶点继续上述操作。直到我们走到的顶点没有与其链接的未标记顶点时,往前回溯,再继续搜索,直到搜索完该点所在的连通分支的全部节点。
请添加图片描述
in algorithm.h

class DFS
{
public:
	DFS(graph g,int s);
	int num()
	{
		return count;
	}
private:
	bool *marked;
	int count;
	void dfs(graph g, int v);
	bool mark(int v);
};

in algorithm.cpp

/*深度优先搜索*/
DFS::DFS(graph g, int s)
{
	marked = new bool[g.numv()];
	std::fill(marked, marked + g.numv(), 0);
	dfs(g, s);
}
bool DFS::mark(int v)
{
	return marked[v];
}
void DFS::dfs(graph g, int v)
{
	marked[v] = true;
	count++;
	std::vector<int> gv = g.iterator(v);
	for (auto w : gv)
	{
		//printf("%d %d\n", w,marked[w]);
		if (!mark(w))
		{
			dfs(g, w);
		}
	}
}

细心的读者应该注意到了,我这次并没有使用vector,而是使用了数组,不是我良心发现,只是单纯的觉得marked数组不需要什么操作,用数组快一点
 
以上代码就是DFS的核心部分,不过我们在应用时常常对部分代码进行更改使其能达到我们预期的功能,不如我们使用DFS来搜索路径,代码如下:

in algorithm.h

class DFS
{
public:
	DFS(graph g,int s);
	int num()
	{
		return count;
	}
	std::string path_to(int v);
private:
	bool *marked;
	int count;
	std::vector<std::string> path;
	void dfs(graph g, int v);
	bool mark(int v);
};

in alorithm.cpp

/*深度优先搜索*/
DFS::DFS(graph g, int s)
{
	marked = new bool[g.numv()];
	std::fill(marked, marked + g.numv(), 0);
	path.resize(g.numv());
	path[s] += std::to_string(s);
	dfs(g, s);
}
bool DFS::mark(int v)
{
	return marked[v];
}
void DFS::dfs(graph g, int v)
{
	marked[v] = true;
	count++;
	std::vector<int> gv = g.iterator(v);
	for (auto w : gv)
	{
		//printf("%d %d\n", w,marked[w]);
		if (!mark(w))
		{
			path[w] = path[v] + " " + std::to_string(w);	//将顶点转换为字符串压入数组
			dfs(g, w);
		}
	}
}
std::string DFS::path_to(int v)
{
	return path[v];
}

运行结果:
在这里插入图片描述

此处我写的获取路径代码与原书中不太一样,因为我觉得原书中的代码过于含糊与麻烦所以对其进行了修改。

我们也可以用DFS来求图的连通性,不过比起union-find算法虽然DFS在理论上更快,但是实际操作起来,DFS需要构造好的图,并且每当图发生变化,都需要图重新构造。而union-find是动态算法。所以如果仅仅是求连通性,union-find算法实际上会比DFS更快

DFS是非常重要的算法,很多与图有关的操作都需要DFS,所以需要牢牢掌握

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值