Add BFS, DFS, bfs, dfs, move graph_demo() to a seperate file . All tests passed.

This commit is contained in:
Shine wOng
2019-06-04 21:30:06 +08:00
parent 3880e2125a
commit 30b5090612
5 changed files with 169 additions and 18 deletions

View File

@@ -3,6 +3,7 @@
#include "../chp2/Vector.h"
#include "../chp4/Stack.h"
#include "../chp4/Queue.h"
typedef enum { UNDISCOVERED, DISCOVERED, VISITED } VStatus;
typedef enum { UNDETERMINED, TREE, BACKWARD, FORWARD, CROSS } Etype;
@@ -11,7 +12,7 @@ typedef enum { UNDETERMINED, TREE, BACKWARD, FORWARD, CROSS } Etype;
template <typename Tv, typename Te>
class Graph{
private:
void reset();
void reset(); //reset all information of all vertices and edges
void BFS(int, int&);
void DFS(int, int&);
void BCC(int, int&, Stack<int>&);
@@ -54,4 +55,91 @@ public:
template <typename PU> void pfd(int, PU);
};
//private methods
template <typename Tv, typename Te>
void Graph<Tv, Te>::reset(){//reset all information of all vertices and edges
for(int ix = 0; ix != num_of_vertices; ++ix){
status(ix) = UNDISCOVERED;
priority(ix) = 0;
dtime(ix) = -1;
ftime(ix) = -1;
parent(ix) = -1;
for (int jx = 0; jx != num_of_vertices; ++jx)
if(exists(ix, jx)) type(ix, jx) = UNDETERMINED;
}
}
template <typename Tv, typename Te>
void Graph<Tv, Te>::BFS(int x, int &clock){
Queue<int> Q;
int neighbor;
Q.enqueue(x);
status(x) = DISCOVERED;
while(!Q.empty()){
x = Q.dequeue();
dtime(x) = ++clock;
for (neighbor = firstNeighbor(x); neighbor != -1; neighbor = nextNeighbor(x, neighbor)){
if (status(neighbor) == UNDISCOVERED) {
status(neighbor) = DISCOVERED;
type(x, neighbor) = TREE;
parent(neighbor) = x;
Q.enqueue(neighbor);
}
else type(x, neighbor) = CROSS;
}
status(x) = VISITED;
}
}
template <typename Tv, typename Te>
void Graph<Tv, Te>::DFS(int x, int& clock){
dtime(x) = ++clock;
status(x) = DISCOVERED;
for(int neighbor = firstNeighbor(x); neighbor != -1; neighbor = nextNeighbor(x, neighbor)){
switch(status(neighbor)){
case UNDISCOVERED:
type(x, neighbor) = TREE;
parent(neighbor) = x;
DFS(neighbor, clock);
break;
case DISCOVERED:
type(x, neighbor) = BACKWARD;
break;
case VISITED:
default:
if (dtime(x) < dtime(neighbor)) type(x, neighbor) = FORWARD;
else type(x, neighbor) = CROSS;
break;
}
}
ftime(x) = ++clock;
status(x) = VISITED;
}
//Graph related algorithms
template <typename Tv, typename Te>
void Graph<Tv, Te>::bfs(int start){
reset();
int x = start;
int clock = 0;
do {
if (status(x) == UNDISCOVERED)
BFS(x, clock);
} while ((x = ++x % num_of_vertices) != start);
}
template <typename Tv, typename Te>
void Graph<Tv, Te>::dfs(int start){
reset();
int clock = 0;
int x = start;
do{
if (status(x) == UNDISCOVERED)
DFS(x, clock);
} while ((x = ++x % num_of_vertices) != start);
}
#endif

View File

@@ -0,0 +1,17 @@
#include "GraphMatrix.h"
//application interfaces
void graph_demo(GraphMatrix<char, int> &G) {
G = GraphMatrix<char, int>();
char *alphabet = "abcdefghijklmnopqrstuvwxyz";
for (int ix = 0; ix != 10; ++ix)
G.insertVertex(alphabet[ix]);
G.insertEdge(1, 0, 1);
G.insertEdge(1, 0, 7);
G.insertEdge(1, 4, 2);
G.insertEdge(1, 5, 4);
G.insertEdge(1, 5, 3);
G.insertEdge(1, 6, 7);
G.insertEdge(1, 9, 6);
G.insertEdge(1, 3, 8);
}

View File

@@ -128,20 +128,4 @@ Te GraphMatrix<Tv, Te>::removeEdge(int src, int tail){
return edgeBak;
}
//application interfaces
void graph_demo(GraphMatrix<char, int> &G) {
G = GraphMatrix<char, int>();
char *alphabet = "abcdefghij";
for (int ix = 0; ix != 10; ++ix)
G.insertVertex(alphabet[ix]);
G.insertEdge(1, 0, 1);
G.insertEdge(1, 0, 7);
G.insertEdge(1, 4, 2);
G.insertEdge(1, 5, 4);
G.insertEdge(1, 5, 3);
G.insertEdge(1, 6, 7);
G.insertEdge(1, 9, 6);
G.insertEdge(1, 3, 8);
}
#endif

View File

@@ -0,0 +1,62 @@
#include "GraphMatrix.h"
#include <iostream>
#include <cassert>
using std::cout;
using std::endl;
void test_bfs();
void test_dfs();
int main(){
cout << "Running tests." << endl;
test_bfs();
test_dfs();
cout << "All tests passed." << endl;
system("pause");
return 0;
}
void test_bfs(){
GraphMatrix<char, int> G;
graph_demo(G);
G.bfs(0);
assert(G.dtime(0) == 1);
assert(G.dtime(1) == 3);
assert(G.dtime(2) == 4);
assert(G.dtime(3) == 5);
assert(G.dtime(4) == 7);
assert(G.dtime(5) == 8);
assert(G.dtime(6) == 9);
assert(G.dtime(7) == 2);
assert(G.dtime(8) == 6);
assert(G.dtime(9) == 10);
}
void test_dfs(){
GraphMatrix<char, int> G;
graph_demo(G);
G.dfs(0);
assert(G.dtime(0) == 1);
assert(G.dtime(1) == 4);
assert(G.dtime(2) == 7);
assert(G.dtime(3) == 9);
assert(G.dtime(4) == 13);
assert(G.dtime(5) == 15);
assert(G.dtime(6) == 17);
assert(G.dtime(7) == 2);
assert(G.dtime(8) == 10);
assert(G.dtime(9) == 19);
assert(G.ftime(0) = 6);
assert(G.ftime(1) = 5);
assert(G.ftime(2) = 8);
assert(G.ftime(3) = 12);
assert(G.ftime(4) = 14);
assert(G.ftime(5) = 16);
assert(G.ftime(6) = 18);
assert(G.ftime(7) = 3);
assert(G.ftime(8) = 11);
assert(G.ftime(9) = 20);
}

View File

@@ -9,7 +9,7 @@ void test_vertex_insert();
void test_vertex_delete();
void test_edge_insert();
int main(){
int GraphMatrix_test_main(){
cout << "Running tests" << endl;
test_constructor();