带权图 Weighted Graph
程序实现如下
#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;
}
“DenseGraph.h”
#include <iostream>
#include <vector>
#include <cassert>
#ifndef _EDGE_H_
#define _EDGE_H_
#include "Edge.h"
#endif // _SORTINGHELP_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,(Edge<Weight>*)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();
}
};
};
“SparseGraph.h”
#include <iostream>
#include <vector>
#include <cassert>
#ifndef _EDGE_H_
#define _EDGE_H_
#include "Edge.h"
#endif // _SORTINGHELP_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 = false;
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++;
if (index < G.g[v].size())
return G.g[v][index];
return NULL;
}
bool end(){
return index >= G.g[v].size();
}
};
};
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();
}
};
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.c_str());
string line;
int V,E;
assert( file.is_open() );
assert( getline(file, line) );
stringstream ss(line);
ss>>V>>E;
assert( V == graph.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 );
}
}
};
输出为