DenseGraph.h
#ifndef GRAPH_DENSEGRAPH_H
#define GRAPH_DENSEGRAPH_H
#include <iostream>
#include <vector>
#include <cassert>
using namespace std;
// 稠密图 - 邻接矩阵
class DenseGraph{
private:
int n, m;
bool directed;
vector<vector<bool>> 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<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:
DenseGraph &G;
int v;
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
SparseGraph.h
#ifndef GRAPH_SPARSEGRAPH_H
#define GRAPH_SPARSEGRAPH_H
#include <iostream>
#include <vector>
#include <cassert>
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;}
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 ++;
}
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 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(){
index = 0;
if( G.g[v].size() )
return G.g[v][index];
return -1;
}
int next(){
index += 1;
if( index < G.g[v].size() )
return G.g[v][index];
return -1;
}
bool end(){
return index >= G.g[v].size();
}
};
};
#endif
ReadGraph.h
#ifndef GRAPH_READGRAPH_H
#define GRAPH_READGRAPH_H
#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
#include <cassert>
using namespace std;
template <typename Graph>
class ReadGraph{
public:
ReadGraph(Graph &graph, const string &filename){
ifstream file(filename);
string line;
int V, E;
assert(file.is_open());
//cout<<"open "<<filename<<" successfully."<<endl;
assert( getline(file,line));
stringstream ss(line);
ss>>V>>E;
assert( graph.V() == V );
//cout<<"V = "<<V<<" , E = "<<E<<" , in "<<filename<<"."<<endl;
for( int i = 0 ; i < E ; i ++ ){
//cout<<"read line "<<i<<endl;
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
Component.h
#ifndef GRAPH_COMPONENT_H
#define GRAPH_COMPONENT_H
#include <iostream>
#include <cassert>
using namespace std;
template <typename Graph>
class Component{
private:
Graph &G;
bool* visited;
int ccount = 0;
int *id;
void dfs( int v ){
visited[v] = true;
id[v] = ccount;
typename Graph::adjIterator adj(G,v);
for( int i = adj.begin() ; !adj.end() ; i = adj.next() )
if( !visited[i] )
dfs(i);
}
public:
Component(Graph &graph):G(graph){
visited = new bool[G.V()];
id = new int[G.V()];
for( int i = 0 ; i < G.V() ; i ++ ){
visited[i] = false;
id[i] = -1;
}
ccount = 0;
for( int i = 0 ; i < G.V() ; i ++ )
if( !visited[i] ){
dfs(i);
ccount += 1;
}
}
~Component(){
delete [] visited;
delete [] id;
}
int count(){
return ccount;
}
bool isConnected( int v , int w ){
assert( v >= 0 && v < G.V() );
assert( w >= 0 && w < G.V() );
assert( id[v] != -1 && id[w] != -1 );
return id[v] == id[w];
}
};
#endif
RandomGraph.h
#ifndef GRAPH_RANDOMGRAPH_H
#define GRAPH_RANDOMGRAPH_H
#include <iostream>
#include <ctime>
using namespace std;
template <typename Graph>
class RandomGraph{
public:
RandomGraph( Graph &graph, int V, int E){
double p = (double)2*E / (V*(V-1));
srand(time(NULL));
for( int i = 0 ; i < V ; i ++ )
for( int j = i+1 ; j < V ; j ++ ){
double randomValue = (double)rand() / RAND_MAX;
if( randomValue < p ){
graph.addEdge(i,j);
}
}
}
};
#endif
Path.h
#ifndef GRAPH_PATH_H
#define GRAPH_PATH_H
#include <vector>
#include <stack>
#include <iostream>
#include <cassert>
using namespace std;
template <typename Graph>
class Path{
private:
Graph &G;
int s;
bool* visited;
int * from;
void dfs(int v){
visited[v] = true;
typename Graph::adjIterator adj(G,v);
for( int i = adj.begin() ; !adj.end() ; i = adj.next() )
if( !visited[i] ){
from[i] = v;
dfs(i);
}
}
public:
Path(Graph &graph, int s):G(graph){
// 算法初始化
assert( s >= 0 && s < G.V() );
visited = new bool[G.V()];
from = new int[G.V()];
for( int i = 0 ; i < G.V() ; i ++ ){
visited[i] = false;
from[i] = -1;
}
this->s = s;
// 寻路算法
dfs(s);
}
~Path(){
delete [] visited;
delete [] from;
}
bool hasPath(int w){
assert( w >= 0 && w < G.V() );
return visited[w];
}
void path(int w, vector<int> &vec){
assert( w >= 0 && w < G.V() );
stack<int> s;
int p = w;
while( p != -1 ){
s.push(p);
p = from[p];
}
vec.clear();
while( !s.empty() ){
vec.push_back( s.top() );
s.pop();
}
}
void showPath(int w){
assert( w >= 0 && w < G.V() );
vector<int> vec;
path(w, vec);
for( int i = 0 ; i < vec.size() ; i ++ ){
cout<<vec[i];
if( i == vec.size()-1 )
cout<<endl;
else
cout<<" -> ";
}
}
};
#endif
ShortestPath.h
#ifndef GRAPH_SHORTESTPATH_H
#define GRAPH_SHORTESTPATH_H
#include <vector>
#include <queue>
#include <stack>
#include <iostream>
#include <cassert>
using namespace std;
template <typename Graph>
class ShortestPath{
private:
Graph &G;
int s;
bool *visited;
int *from;
int *ord;
public:
ShortestPath(Graph &graph, int s):G(graph){
// 算法初始化
assert( s >= 0 && s < graph.V() );
visited = new bool[graph.V()];
from = new int[graph.V()];
ord = new int[graph.V()];
for( int i = 0 ; i < graph.V() ; i ++ ){
visited[i] = false;
from[i] = -1;
ord[i] = -1;
}
this->s = s;
queue<int> q;
// 无向图最短路径算法
q.push( s );
visited[s] = true;
ord[s] = 0;
while( !q.empty() ){
int v = q.front();
q.pop();
typename Graph::adjIterator adj(G,v);
for( int i = adj.begin() ; !adj.end() ; i = adj.next() )
if( !visited[i] ){
visited[i] = true;
from[i] = v;
ord[i] = ord[v] + 1;
q.push(i);
}
}
}
~ShortestPath(){
delete [] visited;
delete [] from;
delete [] ord;
}
bool hasPath(int w){
assert( w >= 0 && w < G.V() );
return visited[w];
}
int length(int w){
assert( w >= 0 && w < G.V() );
return ord[w];
}
void path(int w, vector<int> &vec){
assert( w >= 0 && w < G.V() );
stack<int> s;
int p = w;
while( p != -1 ){
s.push(p);
p = from[p];
}
vec.clear();
while( !s.empty() ){
vec.push_back( s.top() );
s.pop();
}
}
void showPath(int w){
assert( w >= 0 && w < G.V() );
vector<int> vec;
path(w, vec);
for( int i = 0 ; i < vec.size() ; i ++ ){
cout<<vec[i];
if( i == vec.size()-1 )
cout<<endl;
else
cout<<" -> ";
}
}
};
#endif
main_component.cpp
#include <iostream>
#include <vector>
#include <ctime>
#include "DenseGraph.h"
#include "SparseGraph.h"
#include "RandomGraph.h"
#include "Component.h"
using namespace std;
int main() {
// Test Random Graph Component
int V = 100;
int E = V*(V-1)/2/10;
bool directed = false;
SparseGraph g1 = SparseGraph(V, directed);
RandomGraph<SparseGraph>(g1, V, E);
Component<SparseGraph> component1(g1);
cout<<"Test Random Graph, Component Count: "<<component1.count()<<endl;
return 0;
}
main_component2.cpp
#include <iostream>
#include <vector>
#include <ctime>
#include <string>
#include "DenseGraph.h"
#include "SparseGraph.h"
#include "Component.h"
#include "ReadGraph.h"
using namespace std;
int main() {
// TestG1.txt
string filename1 = "testG1.txt";
SparseGraph g1 = SparseGraph(13, false);
ReadGraph<SparseGraph> readGraph1(g1, filename1);
Component<SparseGraph> component1(g1);
cout<<"TestG1.txt, Component Count: "<<component1.count()<<endl;
cout<<endl;
// TestG2.txt
string filename2 = "testG2.txt";
SparseGraph g2 = SparseGraph(7, false);
ReadGraph<SparseGraph> readGraph2(g2, filename2);
Component<SparseGraph> component2(g2);
cout<<"TestG2.txt, Component Count: "<<component2.count()<<endl;
return 0;
}
main_path.cpp
#include <iostream>
#include <vector>
#include <ctime>
#include <string>
#include "DenseGraph.h"
#include "SparseGraph.h"
#include "Path.h"
#include "ShortestPath.h"
#include "ReadGraph.h"
using namespace std;
int main() {
string filename = "testG2.txt";
SparseGraph g = SparseGraph(7, false);
ReadGraph<SparseGraph> readGraph(g, filename);
g.show();
cout<<endl;
Path<SparseGraph> dfs(g,0);
cout<<"DFS : ";
dfs.showPath(6);
ShortestPath<SparseGraph> bfs(g,0);
cout<<"BFS : ";
bfs.showPath(6);
return 0;
}
main_test.cpp
#include <iostream>
#include <vector>
#include <ctime>
#include "DenseGraph.h"
#include "SparseGraph.h"
#include "RandomGraph.h"
using namespace std;
int main() {
int V = 100;
int E = V*V/10;
bool directed = false;
SparseGraph sparseGraph = SparseGraph(V, directed);
RandomGraph<SparseGraph>(sparseGraph, V, E);
cout<<"test sparse adjance"<<endl;
SparseGraph::adjIterator sparseAdj(sparseGraph, 0);
for( int i = sparseAdj.begin() ; !sparseAdj.end() ; i = sparseAdj.next() )
cout<<i<<" ";
cout<<endl;
DenseGraph denseGraph = DenseGraph(V, directed);
RandomGraph<DenseGraph>(denseGraph, V, E);
cout<<"test dense adjance"<<endl;
DenseGraph::adjIterator denseAdj(denseGraph, 0);
for( int i = denseAdj.begin() ; !denseAdj.end() ; i = denseAdj.next() )
cout<<i<<" ";
cout<<endl;
return 0;
}
main.cpp
#include <iostream>
#include <ctime>
#include "DenseGraph.h"
#include "SparseGraph.h"
using namespace std;
int main(){
int N = 20;
int M = 100;
srand( time(NULL) );
// Sparse Graph
SparseGraph g1(N , false);
for( int i = 0 ; i < M ; i ++ ){
int a = rand()%N;
int b = rand()%N;
g1.addEdge( a , b );
}
for( int v = 0 ; v < N ; v ++ ){
cout<<v<<" : ";
SparseGraph::adjIterator adj( g1 , v );
for( int w = adj.begin() ; !adj.end() ; w = adj.next() )
cout<<w<<" ";
cout<<endl;
}
cout<<endl;
// Dense Graph
DenseGraph g2(N , false);
for( int i = 0 ; i < M ; i ++ ){
int a = rand()%N;
int b = rand()%N;
g2.addEdge( a , b );
}
for( int v = 0 ; v < N ; v ++ ){
cout<<v<<" : ";
DenseGraph::adjIterator adj( g2 , v );
for( int w = adj.begin() ; !adj.end() ; w = adj.next() )
cout<<w<<" ";
cout<<endl;
}
return 0;
}
testG1.txt
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
testG2.txt
7 8
0 1
0 2
0 5
0 6
3 4
3 5
4 5
4 6

被折叠的 条评论
为什么被折叠?



