图算法模板

9 篇文章 0 订阅

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

//防止多重引用 
#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:
		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




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值