算法笔记_图算法专题_图的存储和遍历

图的存储和遍历

1.图的基本知识

1.表示方法:G(V,E)  V为点集,E为边集

2.图的分类:有向图和无向图

3.顶点的度:指和顶点相连的边的条数。对于有向图来说,顶点的出边条数为出度,顶点的入边条数称为入度。

4.权值:顶点的权值称为点权,边的权值称为边权。

5.连通分量:只针对无向图而言,图G的极大连通子图为连通分量,连通图则只有一个连通分量,而非连通图有多
           个连通分量。
  强连通分量:只针对有向图而言,图G的极大连通子图为强连通分量,连通图则只有一个连通分量,而非连通图
  		     有多个连通分量。

2.图的存储方式

1)邻接矩阵
int G[N][N];  //G[i][i]可存放边权,不存在的边可以存0,-1,或一个很大的数。
对于无向图来说,邻接矩阵是一个对称矩阵。N为结点数量。
2)邻接表
struct Node{
	int v; //边的终点编号
	int w; //边权 
	Node(int _v,int _w):v(_v),w(_w){}//构造函数
}; 

vector<Node> Adj[N];//N为结点数量
Adj[i].push_back(Node(3,4));

3.图的遍历

1)DFS遍历图
伪代码:
	DFS(u){
		vis[u] = true;
		for(从u出发能到达的所有顶点v){
			if vis[v] == false
				DFS(v);
		}
	}
	//用于访问到每一个连通分量,如果是连通图则没必要写DFSTrave
	DFSTrave(G){
		for(G的所有顶点u){
			if vis[u] == false
				DFS(u);
		}
	}


邻接矩阵版:
    //u为起始节点,v为终点
	int n,G[MAXV][MAXV];
	bool vis[MAXV] = {false};
	
	void DFS(int u,int depth){
		vis[u] = true;
		//可以在这个位置对u进行一些操作,比如输出
		for(int v=0;v<n;v++){
			if(G[u][v]!=INF&&vis[v]==false){
				DFS(v,depth+1);
			}
		} 
	} 
	
	void DFSTrave(){
		for(int u=0;u<n;u++){
			if(vis[u]==false){
				DFS(u,1);
			}
		}
	}
	
	
邻接表版:
    //u为起始节点,v为终点
	struct Node{
		int v; //边的终点编号
		int w; //边权 
		Node(int _v,int _w):v(_v),w(_w){}//构造函数
	}; 
	
	vector<Node> Adj[MAXV];//N为结点数量
	int n;
	bool vis[MAXV] = {false};
	
	void DFS(int u,int depth){
		vis[u] = true;
		//可以在这个位置对u进行一些操作,比如输出
		for(int i=0;v<Adj[u].size();i++){
			int v = Adj[u][i].v;
			if(vis[v]==false){
				DFS(v,depth+1);
			}
		}
	}
	
	void DFSTrave(){
		for(int u=0;u<n;u++){
			if(vis[u]==false){
				DFS(u,1);
			}
		}
	}
2)BFS遍历图
伪代码:
	BFS(u){
		queue q;
		将u入队;
		inq[u] = true; //设置u已被加入过队列 
		while(q非空){
			取出q的队首元素u进行访问;
			for(从u出发的可达的所有顶点v){
				if(inq[v]==false){
					将v入队;
					inq[v] = true; 
				}
			} 
		}
	} 
	
	BFSTrave(G){
		for(G的所有顶点u){
			if(inq[u]==false){
				BFS(u);
			}
		}
	} 

邻接矩阵版:
	//u为起始节点,v为终点
	int n,G[MAXV][MAXV];
	bool inq[MAXV] = {false};
	
	void BFS(int u){
		queue<int> q;
		q.push(u);
		inq[u] = true;
		while(!q.empty()){
			int u = q.front();
			q.pop();
			for(int v=0;v<n;v++){
				if(G[u][v]!=INF&&inq[v]==false){
					q.push(v);
					inq[v] = true;
				}
			}
		} 
	} 
	
	void BFSTrave(){
		for(int u=0;u<n;u++){
			if(inq[u]==false){
				BFS(q);
			}
		}
	}

邻接表版(可以求顶点层号):
	struct Node{
		int v;//顶点编号 
		int layer;//顶点层号 
	}; 
	
	vector<Node> Adj[MAXV];
	int n;
	bool inq[MAXV] = {false};
	
	void BFS(int u){
		queue<Node> q;
		Node start;
		
		start.v = s;
		start.layer = 0;
		
		q.push(start);
		inq[start.v] = true;
		while(!q.empty()){
			Node topNode = q.front();
			q.pop();
			int u = topNode.v;
			for(int i=0;i<Adj[u].size();i++){
				Node next = Adj[u][i];
				next.layer = topNode.layer+1;
				if(inq[next.v==false]){
					q.push(next);
					inq[next.v] = true;
				}
			}
		} 
	} 
	
	void BFSTrave(){
		for(int u=0;u<n;u++){
			if(inq[u]==false){
				BFS(u);
			}
		}
	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值