您的位置:首页 > 其它

图算法模板

2017-10-29 11:14 127 查看
创建一个对于稀疏图、稠密图都适用的模板,可以以文件的形式传入数据,进行相邻进点的遍历

//防止多重引用
#ifndef INC_04_READ_GRAPH_READGRAPH_H
#define INC_04_READ_GRAPH_READGRAPH_H

#include<iostream>
#include<cassert>
#include<fstream>
#include<sstream>
#include<string>

using namespace std;

//适用于稀疏图、稠密图的算法模板
template<typename Graph>
class ReadGraph{

public:
ReadGraph(Graph &graph,const string &filename){ //传入图的模板、文件名称
//		ifstream file(filename);
ifstream file(filename.c_str());			//读入filename

string line;
int V,E;
assert(file.is_open());		//确定成功打开file

assert(getline(file,line));	//读取:将file中的第一行放入字符串
stringstream ss(line);		//将line放入ss中
ss>>V>>E;					//从stringstream中解析出V、E两个变量

assert(V==graph.V());		//确定:文件中点数与图中的点数一致
//每次读取文件中一行
for(int i=0;i<E;i++){
assert(getline(file,line));
stringstream ss(line);

int a,b;
ss>>a>>b;
assert(a>=0&&a<V);
assert(b>=0&&b<V);
graph.addEdge(a,b);
}
}
};

#endif //INC_04_READ_GRAPH_READGRAPH_H


主方法如下:

#include<iostream>
#include "SparseGraph.h"
#include "DenseGraph.h"
#include "ReadGraph.h"

using namespace std;

int main(){
string filename="testG1.txt";

SparseGraph g1(13,false);
ReadGraph<SparseGraph> readGraph1(g1,filename);
g1.show();
cout<<endl;
return 0;
}
测试的数据
13 13
0 5
4 3
0 1
9 12
6 4
5 4
0 2
11 12
9 10
0 6
7 8
9 11
5 3
稀疏图头文件:

#ifndef INC_04_READ_GRAPH_SPARSEGRAPH_H
#define INC_04_READ_GRAPH_SPARSEGRAPH_H

#include<iostream>
#include<cassert>
#include<vector>
using namespace std;

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;}

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;
}
}

void addEdge(int v,int w){
assert(v>=0&&v<n);
assert(w>=0&&w<n);
g[v].push_back(w);

if(v!=w&&!directed)				//处理自环边或无向图的情况
g[w].push_back(v);
m++;
}

void show(){
for(int i=0;i<n;i++){
cout<<"vertex"<<i<<":\t";
for(int j=0;j<g[i].size();j++)
cout<<g[i][j]<<"\t";
cout<<endl;
}
}

//相邻边迭代器
class adjIterator{
private:
Sparse
4000
Graph &G;
int v;
int index;		//指示遍历到的位置
public:
adjIterator(SparseGraph &graph,int v):G(graph){	//传入遍历的图的对应顶点
this->v=v;
this->index=0;
}

int begin(){		//迭代开始的位置
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 //INC_04_READ_GRAPH_SPARSEGRAPH_H


稠密图头文件:

#ifndef INC_04_READ_GRAPH_DENSEGRAPH_H
#define INC_04_READ_GRAPH_DENSEGRAPH_H

#include<iostream>
#include<vector>
#include<cassert>
using namespace std;

//稠密图(邻接矩阵)定义
class DenseGraph{
private:
int n,m;
vector<vector<bool> > g;			//二位矩阵用来存储点之间的连接关系
bool directed;					//有向图/无向图

public:
DenseGraph(int n,bool directed){
this->n=n;
this->m=0;					//初始边数默认为0
this->directed=directed;
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];
}

void show(){

for( int i = 0 ; i < n ; i ++ ){
for( int j = 0 ; j < n ; j ++ )
cout<<g[i][j]<<"\t";
cout<<endl;
}
}

//定义相邻节点迭代器
class adjIterator{
private:
int v;
DenseGraph &G;
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+=1;index<G.V();index++)
if(G.g[v][index])
return index;
return -1;
}

bool end(){
return index>=G.V();
}
};
};

#endif //INC_04_READ_GRAPH_DENSEGRAPH_H
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: