图的遍历介绍

概念

特点

无论是进行哪种遍历,均需要通过设置辅助数组标记顶点是否被访问来避免重复访问!!!!

类型

深度优先遍历

可以实现一次遍历访问一个连通图中的所有顶点,只要连通就能继续向下访问。

因此,深度递归次数就是图中连通分量数。

遍历过程

类似树的先根遍历,先访问结点,再访问与其邻接的第一个结点。

示例

遍历邻接矩阵表示图的实现

效率分析

非连通图的遍历

广度优先搜索

遍历过程

类似于树的层序遍历,先访问结点,再访问与结点邻接的所有结点。

 

非连通图的遍历

遍历邻接表表示图的实现

效率分析

DFS其底层是借助一个递归工作栈实现的。

而BFS是借助一个辅助队列实现的。

时间复杂度只与存储结构有关!!!!!

代码整合

#include <iostream> 
#define maxn 100
#define infi 333333
using namespace std;
int visit[maxn]={0}; 
//邻接矩阵:顶点数+边数+顶点表(一维)+边表(二维) 
typedef struct node{
	int vnum,arcnum;
	char vexs[maxn];
	int acr[maxn][maxn];
}adjgraph;
//邻接表:顶点数+边数+顶点表==>顶点类型:顶点信息+第一条边==> 边类型:顶点编号+权值+下一条边 
typedef struct acrnode{
	int num;
	int weigh;
	acrnode *nextacr;
}acrnode;
typedef struct vexnode{
	char vex;
	acrnode *firstacr;
}vexnode; 
typedef struct node{
	int vnum,acrnum;
	vexnode vexs[maxn];
}listgraph;

//深度遍历 
//递归实现:传入图与起点,不断调用自身 
//用邻接矩阵实现 
void dfs1(adjgraph g,int v){ 
	cout<<v<<endl;
	visit[v]=1;
	for(int i=0;i<g.vnum;i++){
		if(visit[i]==0&&acr[v][i]!=infi)
		dfs(g,i);
	}
}
//用邻接表实现 
void dfs2(listgraph l,int v){
	acrnode edge;
	vexnode vex; 
	cout<<v<<endl;
	visit[v]=1;
	for(edge=l.vexs[v].firstacr;edge;edge=edge.nextacr){//遍历与v相连的所有边-有边 
	     vex=l.vexs;//记录结点
		 if(!visit[vex]) //且未被访问 
		 dfs(l,vex);//访问结点 
	}
}

//非递归实现:通过栈实现
//1.初始栈和标志数组
//2.起点元素入栈,
//3.栈非空:出栈访问,遍历下一条邻接边,未被访问时入栈,取下一个邻接结点 
stack<int> s
void dfs(adjgraph g,int v){//邻接矩阵实现 
	int t;
	initstack(s);
	push(s,v);
	while(!empty(s)){
		t=pop(s,v);
		if(!visit[t]){
			cout<<t<<endl;
			visit[t]=1;
		}
		for(int i=0;i<g.vnum;i++){
			if(g.arcnum[v][i]!=infi&&(!visit[i]))
			{
				push(s,i);
			}
		}
	}
}


//广度遍历
1.初始队列与标记数组
2.起点元素入队,
3.队非空:出队,遍历边,未被访问时访问入队 
void bfs(listgraph l,int v) {
	//用队列实现
	acrnode w;
	cout<<v<<endl;
	visit[v]=1;
	init(q); enqueue(q,v);
	while(!isempty(q)) {
		dequeue(q,v);
		for(w=l.vexs[v].firstacr;w;w=w.nextacr)//遍历邻接的所有边 
		{
			if(!visit[w]){
				cout<<w<<endl;
				visit[w]=1;
				enqueue(q,w);
			}
		}
	}
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值