1.稠密图的基本实现:
#ifndef UNTITLED1_DENSEGRAPH_H
#define UNTITLED1_DENSEGRAPH_H
#include
#include
#include
using namespace std;
class DenseGraph{
private:
//n是图中节点个数,m是边数
int n,m;
//directed指明图是有向的还是无向的
bool directed;
vector<vector> g;
public:
DenseGraph(int n, bool directed){
this->n = n;
this->m = 0;
this->directed = directed;
for(int i=0;i < n;i ++)
g.push_back( vector(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)
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();
}
int next(){
for(index++;index<G.V();index++){
if(G.g[v][index])
return index;
}
return -1;
}
bool end(){
return index >= G.V();
}
};
};
2.稀疏图的基本实现:
#ifndef UNTITLED1_SPARSEGRAPH_H
#define UNTITLED1_SPARSEGRAPH_H
#include
#include
#include
using namespace std;
class SparseGraph{
private:
int n, m;
bool directed;
vector<vector> 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());
}
~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);
g[v].push_back(w);
//判断v!=w来避免自环边
if(v != w && !directed)
g[w].push_back(v);
m ++;
}
bool hasEdge(int v, int m){
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][0];
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();
}
};
};
3.图的应用场景:
交通运输、社交网络、互联网、工作安排、脑区活动、程序状态的执行(自动机)
4.图的分类:
(1)简单图:无自环边,平行边
(2)无向图和有向图:一个节点是否指向另一个节点
(3)无权图和有权图:边上有无数值
(4)完全图:每个节点与其他所有节点都有边
5.邻接矩阵和邻接表
邻接矩阵:适合表示稠密的图,记录了每个节点与其他各节点的连接情况
邻接表:适合表示稀疏图(节点边的个数较它最大能连接的边数小很多)
6.稠密图和稀疏图的区别:
(1)稠密图中的元素是bool值,记录了每个节点与其他各节点的连接情况
稀疏图中的元素是整型或其他类型的数据,只记录与其相邻的边
(2)稠密图用邻接矩阵表示,稀疏图用邻接表表示
7.迭代器的作用:
遍历图时,避免用户无意间修改了图
8.邻接表的缺点:可能保存了自环边
优点:在数据很多而数据之间的关系又不大的情况下使用更加方便