DenseGraph.h
#ifndef INC_07_BFS_AND_SHORTEST_PATH_DENSEGRAPH_H
#define INC_07_BFS_AND_SHORTEST_PATH_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 INC_07_BFS_AND_SHORTEST_PATH_SPARSEGRAPH_H
#define INC_07_BFS_AND_SHORTEST_PATH_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 ++;
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 INC_07_BFS_AND_SHORTEST_PATH_READGRAPH_H
#define INC_07_BFS_AND_SHORTEST_PATH_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() );
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;
ss>>a>>b;
assert( a >= 0 && a < V );
assert( b >= 0 && b < V );
graph.addEdge( a , b );
}
}
};
#endif
ShortestPath.h
#ifndef INC_07_BFS_AND_SHORTEST_PATH_SHORTESTPATH_H
#define INC_07_BFS_AND_SHORTEST_PATH_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] ){
q.push(i);
visited[i] = true;
from[i] = v;
ord[i] = ord[v] + 1;
}
}
}
~ShortestPath(){
delete [] visited;
delete [] from;
delete [] ord;
}
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<<" -> ";
}
}
int length(int w){
assert( w >= 0 && w < G.V() );
return ord[w];
}
};
#endif
main.cpp
#include <iostream>
#include "SparseGraph.h"
#include "DenseGraph.h"
#include "ReadGraph.h"
#include "Path.h"
#include "ShortestPath.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;
}
本文深入探讨了图算法的两种主要实现方式:邻接矩阵和邻接表,并通过具体代码展示了稠密图和稀疏图的创建过程。此外,文章还介绍了如何从文件中读取图数据并构建图结构,以及如何利用广度优先搜索(BFS)算法寻找图中的最短路径。
1519

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



