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

深度优先搜索,即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,所以需要牢牢掌握

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值