From 30b5090612c2f334cf430af14b13fd79e4920795 Mon Sep 17 00:00:00 2001 From: Shine wOng <1551885@tongji.edu.cn> Date: Tue, 4 Jun 2019 21:30:06 +0800 Subject: [PATCH] Add BFS, DFS, bfs, dfs, move graph_demo() to a seperate file . All tests passed. --- thu_dsa/chp6/Graph.h | 90 +++++++++++++++++++++++++++++++- thu_dsa/chp6/GraphMatrix.cpp | 17 ++++++ thu_dsa/chp6/GraphMatrix.h | 16 ------ thu_dsa/chp6/testGraph.cpp | 62 ++++++++++++++++++++++ thu_dsa/chp6/testGraphMatrix.cpp | 2 +- 5 files changed, 169 insertions(+), 18 deletions(-) create mode 100644 thu_dsa/chp6/GraphMatrix.cpp create mode 100644 thu_dsa/chp6/testGraph.cpp diff --git a/thu_dsa/chp6/Graph.h b/thu_dsa/chp6/Graph.h index dd03498..83a904f 100644 --- a/thu_dsa/chp6/Graph.h +++ b/thu_dsa/chp6/Graph.h @@ -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 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&); @@ -54,4 +55,91 @@ public: template void pfd(int, PU); }; +//private methods +template +void Graph::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 +void Graph::BFS(int x, int &clock){ + Queue 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 +void Graph::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 +void Graph::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 +void Graph::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 \ No newline at end of file diff --git a/thu_dsa/chp6/GraphMatrix.cpp b/thu_dsa/chp6/GraphMatrix.cpp new file mode 100644 index 0000000..557422d --- /dev/null +++ b/thu_dsa/chp6/GraphMatrix.cpp @@ -0,0 +1,17 @@ +#include "GraphMatrix.h" + +//application interfaces +void graph_demo(GraphMatrix &G) { + G = GraphMatrix(); + 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); +} diff --git a/thu_dsa/chp6/GraphMatrix.h b/thu_dsa/chp6/GraphMatrix.h index cd4a651..2e255a3 100644 --- a/thu_dsa/chp6/GraphMatrix.h +++ b/thu_dsa/chp6/GraphMatrix.h @@ -128,20 +128,4 @@ Te GraphMatrix::removeEdge(int src, int tail){ return edgeBak; } -//application interfaces -void graph_demo(GraphMatrix &G) { - G = GraphMatrix(); - 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 diff --git a/thu_dsa/chp6/testGraph.cpp b/thu_dsa/chp6/testGraph.cpp new file mode 100644 index 0000000..158d59a --- /dev/null +++ b/thu_dsa/chp6/testGraph.cpp @@ -0,0 +1,62 @@ +#include "GraphMatrix.h" +#include +#include +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 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 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); +} diff --git a/thu_dsa/chp6/testGraphMatrix.cpp b/thu_dsa/chp6/testGraphMatrix.cpp index 5cf8f6c..00a6ac9 100644 --- a/thu_dsa/chp6/testGraphMatrix.cpp +++ b/thu_dsa/chp6/testGraphMatrix.cpp @@ -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();