图的遍历(深搜和宽搜)

深度优先搜索 (Depth First Search)

深度优先搜索也叫深度优先遍历,简称DFS或者深搜。

是基于栈的搜索算法,其过程,是对每一个可能的分支路径深入到不能再深入为止,而且每个结点只能访问一次。

图解:

vF3GY4.jpg

当前访问入栈结点出栈结点栈内结点说明
000以0为根开始遍历
440,4
660,4,6
550,4,6,5
50,4,65的儿子全部遍历,弹栈
60,46的儿子全部遍历,弹栈
770,4,7
70,47遍历完毕,弹栈
404遍历完毕,弹栈
0栈空0遍历完毕,弹栈
111以1为根开始遍历
221,2
212遍历完毕,弹栈
331,3
313遍历完毕,弹栈
1栈空1遍历完毕,弹栈

邻接表:

void DFS(int u)
{
	visited[u]=1;//printf("%d ",u);//用于验证的输出
	for(int i=adj[u];i;i=e[i].nxt)//深度优先的遍历
	{
		int v=e[i].to;
			if(visited[v] == 1) continue;
		DFS(v);//用递归来形成栈
	}
}
int main()
{
	int n,m;scanf("%d%d",&n,&m);//n是结点数,m是边数
	for(int i=1;i<=m;++i)
	{
		int u,v; scanf("%d%d",&u,&v);
		addedge(u,v);//有向图
	}
	for(int i=0;i<n;++i){
		if(visited[i] == 0)
			DFS(i);
		//printf("\n");//用于验证的输出
	}
	return 0;
}

邻接矩阵:

bool visited[MAXN];
bool G[MAXN][MAXN];
void DFS(int u)
{
    vis[u]=1;
    for(int i=1;i<=n;++i)
    {
        if(G[u][i] == 0) continue;//如果不连接
        if(visited[i]==1)continue;//如果已经访问
        DFS(i);
    }
}

上面图例的数据:

/*上图数据
7 13
1 0
1 3
3 1
1 2
3 2
0 4
5 4
6 5
4 7
7 5
3 7
0 7
4 6
*/ 

宽度优先搜索(Breadth First Search)

宽度优先搜索也叫宽度优先遍历,或是广度优先遍历,简称BFS或者宽搜。

是基于队列的搜索算法,其过程,是将一个点所有邻接点都遍历完再往下搜索。

还是上面那张图:以0,1为根的宽搜序列为:0,4,7,6,5,1,2,3。

当前访问入队列出队列队列内结点说明
000以0为根开始遍历
00出队列
444从4开始遍历0的儿子
774,7
474出队列
667,6从6开始遍历4的儿子
767出队列
556,5从5开始遍历7的儿子
656出队列
55出队列
111以1为根开始遍历
11出队列
222从2开始遍历1的儿子
332,3
232出队列
33出队列

邻接表:

void BFS(int u)//用STL的队列
{
	q.push(u); visited[u]=1;//visited表示已访问
	while(!q.empty())
	{
		int u=q.front();q.pop();
		for(int i=adj[u];i;i=e[i].nxt) 
		{
			int v=e[i].to;
				if(visited[v] == 1) continue;
			visited[v]=1;
			q.push(v);
		}
	}
}

对比

深度优先搜索用栈来实现,整个过程可以想象成一个倒立的树形:

1、把根节点压入栈中。

2、每次从栈中弹出一个元素,搜索所有在它下一级的元素,把这些元素压入栈中。并把这个元素记为它下一级元素的前驱。

3、找到所要找的元素时结束程序。

4、如果遍历整个树还没有找到,结束程序。

广度优先搜索使用队列(queue)来实现,整个过程也可以看做一个倒立的树形:

1、把根节点放到队列的末尾。

2、每次从队列的头部取出一个元素,查看这个元素所有的下一级元素,把它们放到队列的末尾。并把这个元素记为它下一级元素的前驱。

3、找到所要找的元素时结束程序。

4、如果遍历整个树还没有找到,结束程序。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值