DenseGraph.h
#ifndef INC_01_WEIGHTED_GRAPH_DENSEGRAPH_H
#define INC_01_WEIGHTED_GRAPH_DENSEGRAPH_H
#include <iostream>
#include <vector>
#include <cassert>
#include "Edge.h"
using namespace std;
// 稠密图 - 邻接矩阵
template <typename Weight>
class DenseGraph{
private:
int n, m;
bool directed;
vector<vector<Edge<Weight> *>> 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<Edge<Weight> *>(n,NULL) );
}
}
~DenseGraph(){
for( int i = 0 ; i < n ; i ++ )
for( int j = 0 ; j < n ; j ++ )
if( g[i][j] != NULL )
delete g[i][j];
}
int V(){ return n;}
int E(){ return m;}
void addEdge( int v, int w , Weight weight ){
assert( v >= 0 && v < n );
assert( w >= 0 && w < n );
if( hasEdge( v , w ) ){
delete g[v][w];
if( !directed )
delete g[w][v];
m --;
}
g[v][w] = new Edge<Weight>(v, w, weight);
if( !directed )
g[w][v] = new Edge<Weight>(w, v, weight);
m ++;
}
bool hasEdge( int v , int w ){
assert( v >= 0 && v < n );
assert( w >= 0 && w < n );
return g[v][w] != NULL;
}
void show(){
for( int i = 0 ; i < n ; i ++ ){
for( int j = 0 ; j < n ; j ++ )
if( g[i][j] )
cout<<g[i][j]->wt()<<"\t";
else
cout<<"NULL\t";
cout<<endl;
}
}
class adjIterator{
private:
DenseGraph &G;
int v;
int index;
public:
adjIterator(DenseGraph &graph, int v): G(graph){
this->v = v;
this->index = -1;
}
Edge<Weight>* begin(){
index = -1;
return next();
}
Edge<Weight>* next(){
for( index += 1 ; index < G.V() ; index ++ )
if( G.g[v][index] )
return G.g[v][index];
return NULL;
}
bool end(){
return index >= G.V();
}
};
};
#endif
SparseGraph.h
#ifndef INC_01_WEIGHTED_GRAPH_SPARSEGRAPH_H
#define INC_01_WEIGHTED_GRAPH_SPARSEGRAPH_H
#include <iostream>
#include <vector>
#include <cassert>
#include "Edge.h"
using namespace std;
// 稀疏图 - 邻接表
template<typename Weight>
class SparseGraph{
private:
int n, m;
bool directed;
vector<vector<Edge<Weight> *>> 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<Edge<Weight> *>() );
}
~SparseGraph(){
for( int i = 0 ; i < n ; i ++ )
for( int j = 0 ; j < g[i].size() ; j ++ )
delete g[i][j];
}
int V(){ return n;}
int E(){ return m;}
void addEdge( int v, int w , Weight weight){
assert( v >= 0 && v < n );
assert( w >= 0 && w < n );
g[v].push_back(new Edge<Weight>(v, w, weight));
if( v != w && !directed )
g[w].push_back(new Edge<Weight>(w, v, weight));
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]->other(v) == w )
return true;
return false;
}
void show(){
for( int i = 0 ; i < n ; i ++ ){
cout<<"vertex "<<i<<":\t";
for( int j = 0 ; j < g[i].size() ; j ++ )
cout<<"( to:"<<g[i][j]->w()<<",wt:"<<g[i][j]->wt()<<")\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;
}
Edge<Weight>* begin(){
index = 0;
if( G.g[v].size() )
return G.g[v][index];
return NULL;
}
Edge<Weight>* next(){
index += 1;
if( index < G.g[v].size() )
return G.g[v][index];
return NULL;
}
bool end(){
return index >= G.g[v].size();
}
};
};
#endif
Edge.h
#ifndef INC_01_WEIGHTED_GRAPH_EDGE_H
#define INC_01_WEIGHTED_GRAPH_EDGE_H
#include <iostream>
#include <cassert>
using namespace std;
template<typename Weight>
class Edge{
private:
int a,b;
Weight weight;
public:
Edge(int a, int b, Weight weight){
this->a = a;
this->b = b;
this->weight = weight;
}
Edge(){}
~Edge(){}
int v(){ return a;}
int w(){ return b;}
Weight wt(){ return weight;}
int other(int x){
assert( x == a || x == b );
return x == a ? b : a;
}
friend ostream& operator<<(ostream &os, const Edge &e){
os<<e.a<<"-"<<e.b<<": "<<e.weight;
return os;
}
bool operator<(Edge<Weight>& e){
return weight < e.wt();
}
bool operator<=(Edge<Weight>& e){
return weight <= e.wt();
}
bool operator>(Edge<Weight>& e){
return weight > e.wt();
}
bool operator>=(Edge<Weight>& e){
return weight >= e.wt();
}
bool operator==(Edge<Weight>& e){
return weight == e.wt();
}
};
#endif
ReadGraph.h
#ifndef INC_01_WEIGHTED_GRAPH_READGRAPH_H
#define INC_01_WEIGHTED_GRAPH_READGRAPH_H
#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
#include <cassert>
using namespace std;
template <typename Graph, typename Weight>
class ReadGraph{
public:
ReadGraph(Graph &graph, const string &filename){
ifstream file(filename);
string line;
int V, E;
assert(file.is_open());
assert( getline(file,line));
stringstream ss(line);
ss>>V>>E;
assert( graph.V() == V );
for( int i = 0 ; i < E ; i ++ ){
assert( getline(file,line));
stringstream ss(line);
int a, b;
Weight w;
ss>>a>>b>>w;
assert( a >= 0 && a < V );
assert( b >= 0 && b < V );
graph.addEdge(a, b, w);
}
}
};
#endif
testG1.txt
8 16
4 5 .35
4 7 .37
5 7 .28
0 7 .16
1 5 .32
0 4 .38
2 3 .17
1 7 .19
0 2 .26
1 2 .36
1 3 .29
2 7 .34
6 2 .40
3 6 .52
6 0 .58
6 4 .93
main.cpp
#include <iostream>
#include <iomanip>
#include "DenseGraph.h"
#include "SparseGraph.h"
#include "ReadGraph.h"
using namespace std;
int main() {
string filename = "testG1.txt";
int V = 8;
cout<<fixed<<setprecision(2);
// Test Weighted Dense Graph
DenseGraph<double> g1 = DenseGraph<double>(V, false);
ReadGraph<DenseGraph<double>,double> readGraph1(g1, filename);
g1.show();
cout<<endl;
// Test Weighted Sparse Graph
SparseGraph<double> g2 = SparseGraph<double>(V, false);
ReadGraph<SparseGraph<double>,double> readGraph2(g2, filename);
g2.show();
cout<<endl;
return 0;
}