图的存储和遍历
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);
}
}
}