图的学习(三)——BFS与DFS

1.图的广度优先搜索
图的遍历:从图中某一顶点出发,按照某种搜索方法沿着图中的边对图中的所有顶点访问一次且仅访问一次。
广度优先搜索
(1)首先访问起始顶点v;
(2)接着由出发依次访问v的各个未被访问过的邻接顶点 w 1 w_1 w1, w 2 w_2 w2,…, w t w_t wt;
(3)然后依次访问 w 1 w_1 w1, w 2 w_2 w2,…, w t w_t wt的所有未被访问过的邻接顶点;
(4)在从这些访问过的顶点出发,访问它们所有未被访问过的邻接顶点;
(5)…,以此类推;

#define MAX_TREE_SIZE 100
bool visit[MAX_TREE_SIZE];
//避免因为图不连通导致的有结点没有被遍历
void BFSTraverse(Graph G)
{
	for(int i=0;i<G.vexnum;i++)
		visited[i]=false;
	InitQuene(Q);
	for(int i=0;i<G.vexnum;i++)
	{
		if(!visited[i])
			BFS(G,i);
	}	
}
//对某个顶点的广度优先搜索
void BFS(Graph G,int v)
{
	visit(v);
	Enqueue(Q,v);
	visited[v]=true;
	while(!Q.empty())
	{
		Dequeue(Q,v);
		for(w=FirstNeighbor(G,v);w>=0;w=NextNeighbor(G,v,w))
		{
			if(!visited[w])
			{
				visit(w);
				visited[w]=true;
				Enqueue(G,w);
			}
		}
	}
}

复杂度分析:
空间复杂度分析:O(|V|)
时间复杂度:
邻接矩阵法:O( ∣ V ∣ 2 |V|^2 V2)
邻接表法:O(|V|+|E|)
广度优先搜索应用——无权图单源最短路径问题
求解从u到v的任何路径中最少的边数。

Void BFS_MIN_Distance(Graph G,int u)
{
	for(int i=0;i<G.vexnum;i++)
	{
		d[i]=INT_MAX;
	}
	visit(u);
	Enqueue(Q,u);
	d[u]=0;
	visited[u]=true;
	while(!Q.empty())
	{
		Dequeue(Q,v);
		for(w=FirstNeighbor(G,v);w>=0;w=NextNeighbor(G,v,w))
		{
			if(!visited[w])
			{
				visit(w);
				d[w]=d[u]+1;
				visited[w]=true;
				Enqueue(G,w);
			}
		}
	}
}

广度优先生成树
在广度遍历过程中,我们可以得到一棵遍历树,称为广度优先生成树(生成森林)。
**注意:**邻接矩阵的广度优先生成树唯一,邻接表法的不唯一(因为输入边的次序不唯一,对应顶点的边表就不唯一)。

2. 图的深度优先搜索
深度优先搜索DFS:
(1)首先访问起始顶点v;
(2)接着由v出发访问v的任意一个邻接且未被访问的邻接顶点 w i w_i wi;
(3)然后再访问与 w i w_i wi邻接且未被访问过的任意顶点 y i y_i yi;
(4)若 w i w_i wi没有邻接且未被访问的顶点时,退回到它的上一层顶点v;
(5)重复上述过程,直到所有顶点被访问为止。
深度优先搜索与树的前序遍历类似;因此可以采用递归(栈)+辅助标记数组方法进行深度优先搜索。

bool visited[MAX_TREE_SIZE];
void DFSTraversr(Graph G)
{
	for(int i=0;i<G.vernum;i++)
	{
		visited[i]=false;
	}
	for(int i=0;i<G.vernum;i++)
	{
		if(!visited[i])
			DFS(G,i);
	}
}
void DFS(Graph G,int v)
{
	visit(v);
	visited[v]=true;
	for(w=FirstNeighbor(G,v);w>=0;w=NextNeighbor(G,v,w)
	{
		if(!visited[w])
			DFS(G,w);
	}
}

因此,从上述可以看到,递归、回溯是与深度优先搜索捆绑的,而不是广度优先搜索。
DFS算法的性能分析:
空间复杂度(额外添加的空间): O|V| 工作栈
时间复杂度
邻接矩阵法:O| V 2 V^2 V2|
邻接表法:O(|V|+|E|)
深度优先生成树:
在深度遍历过程中,我们可以得到一棵遍历树,称为深度优先生成树。
注意:邻接矩阵的广度优先生成树唯一,邻接表法的不唯一(因为输入边的次序不唯一,对应顶点的边表就不唯一)。
遍历与连通性问题:
在无向图中,在任意结点出发进行
一次遍历
(调用一次DFS或BFS)时,若能访问全部结点,说明该无向图是连通的。
在无向图中,调用遍历函数(BFS或DFS)的次数连通分量的个数

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值