图算法模板

来源:互联网 发布:重庆龙美术馆 知乎 编辑:程序博客网 时间:2024/06/06 03:40

创建一个对于稀疏图、稠密图都适用的模板,可以以文件的形式传入数据,进行相邻进点的遍历

//防止多重引用 #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 130 54 30 19 126 45 40 211 129 100 67 89 115 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:SparseGraph &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




原创粉丝点击