图论——图的遍历

现在我们来思考一个问题,图如何进行遍历?

既然是遍历,我们想要得到的结果就是每条边所对应的两点都输出出来,且保证唯一性【即针对无向图无向网,根据对称性,一条边所对应的两点输出以后,对称的点不再输出】

接下来,我们介绍两种遍历图的思想,两种思想的共性就是他们都是从图中的任意点出发来依次遍历图【由于非连通图较复杂,因此我们下面只讨论连通图】

1.深度优先搜索

类似于树的先序遍历

过程:

  1. 从图中某个顶点v出发,访问v
  2. 找出刚访问过的顶点的未被访问的一个邻接点,访问该邻接点【在这里,我们规定优先访问数值较小的邻接点】。以该邻接点为新顶点,重复此步骤,直至刚访问过的顶点没有未被访问的邻接点
  3. 返回前一个访问过的且仍有其他未被访问的邻接点的顶点,找到该顶点的下一个未被访问的邻接点,访问该邻接点
  4. 重复2和3,直至所有结点都被访问过,搜索结束

 

 代码实现:

图的DFS

void DFS(Graph &G,int v){
	cout<<G.vertex[v]<<" ";//从v位置的顶点出发遍历 
	visited[v]=1;//将此顶点放入已访问数组中,以后不再遍历 
	for(int w=0;w<G.vexnum;++w){//依次访问邻接点 
		if(visited[v]!=1&&G.edge[v][w]!=0){//如果未被访问且两点间有边 
			DFS(G,w);
		}
	}
}

网的DFS【可输出权值】

void DFS_recur(graph &g,int v){
	visited_vex_dfs[v]=1;
	for(int w=0;w<g.vexnum;++w){
		if((visited_vex_dfs[w]==0||visited_vex_dfs[w]==1&&visited_edge_dfs[v][w]==1)&&g.edge[v][w]!=MaxInt){//g.edge[v][w]中w为顶点v的邻接点【逐个访问】,如果不等于MaxInt说明二者之间有边相连 
			cout<<"("<<g.vex[v]<<" "<<g.vex[w]<<") 权值:"<<g.edge[v][w]<<endl;
			visited_edge_dfs[v][w]=0;
			visited_edge_dfs[w][v]=0;
			DFS_recur(g,w);//visited[w]!=0表示此点未被访问 
		}
	}
}

2.广度优先搜索

类似于树的层序遍历

过程:

  1. 从图中顶点v出发,访问顶点v
  2. 然后依次访问v的各个未被访问过的邻接点【仍然是按从小到大】
  3. 接下来从这些邻接点出发依次访问他们的邻接点,重复此步骤,直至顶点都被访问

 

 代码实现:

图的BFS

void BFS(Graph &G,int v){
	cout<<G.vertex[v]<<" ";//从v位置的顶点出发遍历 
	visited[v]=1;//将此顶点放入已访问数组中,以后不再遍历 
	Initqueue(Q);//初始化队列 
	Enqueue(Q,G.vertex[v]);//将此点入队,以便接下来使用 
	while(!IsEmpty(Q)){
		v=Dequeue();//出队,代表接下来对出队的顶点v的邻接点进行遍历 
		for(int w=0;w<G.vexnum;++w){
			if(visited[w]!=0&&G.edge[v][w]!=0){
				cout<<G.vertex[w]<<endl;
				visited[w]=1;
				Enqueue(Q,G.vertex[w]);//入队 
			}
		}
	}
} 

网的BFS

void BFS(graph &g,int v){
	queueCreate();
	visited_vex_bfs[v]=1;
	Enqueue(v);
	while(!isEmpty()){
		v=Dequeue();
		for(int w=0;w<g.vexnum;++w){
			if(g.edge[v][w]!=MaxInt&&(visited_vex_bfs[w]==0||visited_vex_bfs[w]==1&&visited_edge_bfs[v][w]==1)){
				cout<<"("<<g.vex[v]<<" "<<g.vex[w]<<") 权值:"<<g.edge[v][w]<<endl;
				visited_vex_bfs[w]=1;
				visited_edge_bfs[v][w]=0;
				visited_edge_bfs[w][v]=0;
				Enqueue(w);
			}
		}
	}
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值