DenseGraph.h.表示邻接矩阵实现的图,一般邻接矩阵用于较为稠密的图
#ifndef DenseGraph_h
#define DenseGraph_h
#include <iostream>
#include <vector>
#include <cassert>
using namespace std;
//稠密图 --邻接矩阵
class DenseGraph
{
private:
int n,m;//n是节点,m是边数
bool directed;//表示是否是有向图
vector<vector<bool>> g;//用一个二维的vector表示邻接矩阵
public:
DenseGraph(int n,bool directed)//初始状态为矩阵内全为false,表示都不相连
{
this->n=n;
this->directed=directed;
this->m=0;
for(int i=0;i<n;i++)
{
g.push_back(vector<bool>(n,false));
}
}
~DenseGraph()
{
}
int V(){return n;}//获得节点的个数
int E(){return m;}//或者边的条数
void addEdge(int v,int w)
{
assert(v>=0 && v<n);
assert(w>=0 && w<n);
if(hasEdge(v,w))
return;
g[v][w]=true;
if(!directed)
{
g[w][v]=true;
}
m++;
}
bool hasEdge(int v,int w)
{
assert(v>=0 && v<n);
assert(w>=0 && w<n);
return g[v][w];
}
//为图专门设计的迭代器,可以访问某个节点的与之相连接的下一个节点
class adjIterator
{
private:
DenseGraph &G;
int v;
int index;//节点的下标索引
public:
adjIterator(DenseGraph &graph,int v)
:G(graph)
{
this->v=v;
this->index=-1;
}
int begin()
{
index=-1;
return next();//找到第一个不为0的节点
}
int next()
{
for(index+=1;index<G.V();index++)
{
if(G.g[v][index])
return index;
}
return -1;
}
bool end()
{
return index>=G.V();
}
};
};
#endif /* DenseGraph_h */
SparseGraph.h表示稀疏图,一般稀疏图用邻接表表示
#ifndef SparseGraph_h
#define SparseGraph_h
#include <iostream>
#include <vector>
#include <cassert>
using namespace std;
//邻接表--稀疏图
//在遍历邻边的时候,用邻接表时间复杂度为O(k),k为邻边的个数
//要是用邻接矩阵,时间复杂度为O(v),v为所有的顶点个数
class SparseGraph
{
private:
int n,m;
bool directed;
vector<vector<int>> g;
public:
SparseGraph(int n,bool directed)
{
this->n=n;
this->m=0;
this->directed=directed;
for(int i=0;i<n;i++)
{
g.push_back(vector<int>());
}
}
~SparseGraph(){}
int V(){return n;}
int E(){return m;}
void addEdge(int v,int w)
{
assert(v>=0 && v<n);
assert(w>=0 && w<n);
if(hasEdge(v, w))
return;
g[v].push_back(w);
if(v!=w && !directed)
{
g[w].push_back(v);
}
m++;
}
bool hasEdge(int v,int w)
{
assert(v>=0 && v<n);
assert(w>=0 && w<n);
for(int i=0;i<g[v].size();i++)
{
if(g[v][i]==w)
{
return true;
}
}
return false;
}
class adjIterator
{
private:
SparseGraph &G;
int v;
int index;
public:
adjIterator(SparseGraph &graph,int v)
:G(graph)
{
this->v=v;
this->index=0;
}
int begin()
{
index=0;
if(G.g[v].size())
{
return G.g[v][index];
}
return -1;
}
int next()
{
index++;
if(index<G.g[v].size())
{
return G.g[v][index];
}
return -1;
}
bool end()
{
return index >= G.g[v].size();
}
};
};
#endif /* SparseGraph_h */
Component.h表示用深度优先遍历实现的计算连通分量的算法
#ifndef Component_h
#define Component_h
#include <iostream>
#include <cassert>
using namespace std;
template<typename Graph>
class Component
{
private:
Graph &G;
bool *visited;//标记某个节点是否已经被遍历
int ccount;//联通分量的个数
void dfs(int v)
{
visited[v]=true;
typename Graph::adjIterator adj(G,v);
for(int i=adj.begin();!adj.end();i=adj.next())
{
if(!visited[i])
{
dfs(i);
}
}
}
public:
Component(Graph &graph)
:G(graph)
{
visited=new bool[G.V()];
ccount=0;
for(int i=0;i<G.V();i++)
visited[i]=false;
for(int i=0;i<G.V();i++)
{
if(!visited[i])
{
dfs(i); //深度优先遍历
ccount++; //联通分量
}
}
}
~Component()
{
delete []visited;
}
int count()
{
return ccount;
}
};
#endif /* Component_h */
Path.h计算节点的路径
#ifndef Path_h
#define Path_h
#include <iostream>
#include <cassert>
#include <stack>
#include <vector>
using namespace std;
template<typename Graph>
class Path
{
private:
Graph &G;
int s;
bool *visited;
int *from;
void dfs(int v)
{
visited[v]=true;
typename Graph::adjIterator adj(G,v);
for(int i=adj.begin();!adj.end();i=adj.next())
{
if(!visited[i])
{
from[i]=v;
dfs(i);
}
}
}
public:
Path(Graph &graph,int s)
:G(graph)
{
assert(s>=0 && s<G.V());
visited=new bool[G.V()];
from=new int[G.V()];
for(int i=0;i<G.V();i++)
{
visited[i]=false;
from[i]=-1;
}
this->s=s;
}
~Path()
{
delete [] visited;
delete [] from;
}
bool hasPath(int w)
{
return visited[w];
}
void Path(int w,vector<int> &vec)//得到某条路径方法为先用栈保存,然后存进vec中
{
stack<int> s;
int p=w;
while(p!=-1)
{
s.push(p);
p=from[p];
}
vec.clear();
while(!s.empty())
{
vec.push_back(s.top());
s.pop();
}
}
vois showPath(int w)
{
vector<int> vec;
path(w,vec);
for(int i=0;i<vec.size();i++)
{
cout<<vec[i];
if(i==vec.size()-1)
cout<<endl;
else
cout<<" -> ";
}
}
;
#endif /* Path_h */