Skip to content

Commit 135631d

Browse files
committed
Finished BFS and DFS Algorithm of class DiGraph.
1 parent ee35012 commit 135631d

File tree

24 files changed

+980
-174
lines changed

24 files changed

+980
-174
lines changed

Graph/Figures/Forest

13.2 KB
Binary file not shown.

Graph/Figures/Forest.dot

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
digraph
2+
{
3+
1->2;
4+
1->3;
5+
1->4;
6+
3->5;
7+
2->6;
8+
6->7;
9+
6->8;
10+
11+
7[shape="circle",label="F"];
12+
8[shape="circle",label="G"];
13+
6[shape="circle",label="E"];
14+
2[shape="circle",label="A"];
15+
5[shape="circle",label="B"];
16+
3[shape="circle",label="C"];
17+
4[shape="circle",label="D"];
18+
1[shape="circle",label="S"];
19+
}

Graph/Figures/Graph

2.46 KB
Binary file not shown.

Graph/Figures/Graph.dot

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,23 @@
11
digraph
22
{
3-
1->0;
4-
0->2[dir="both"];
5-
1->2;
6-
1->3[dir="both"];
3+
0->1;
4+
0->3;
5+
0->4;
6+
1->3;
7+
1->5;
8+
3->2;
9+
4->2;
10+
7->2;
11+
5->6;
12+
5->7;
13+
7->6;
714

8-
0[shape="circle",label="A"];
9-
1[shape="circle",label="B"];
10-
2[shape="circle",label="C"];
11-
3[shape="circle",label="D"];
15+
0[shape="circle",label="S"];
16+
1[shape="circle",label="A"];
17+
2[shape="circle",label="B"];
18+
3[shape="circle",label="C"];
19+
4[shape="circle",label="D"];
20+
5[shape="circle",label="E"];
21+
6[shape="circle",label="F"];
22+
7[shape="circle",label="G"];
1223
}

Graph/Makefile

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,19 @@
1-
INCLUDE := -I. -I../List
1+
INCLUDE := -I. \
2+
-I../Tree/BinTree \
3+
-I../Tree/Tree \
4+
-I../List/List \
5+
-I../Stack \
6+
-I../Queue/Queue
7+
8+
DEPEND := main.cpp graph.h graph.cpp \
9+
../Tree/BinTree/bintree.h ../Tree/BinTree/bintree.cpp \
10+
../Tree/Tree/tree.h ../Tree/Tree/tree.cpp \
11+
../List/List/list.h ../List/List/list.cpp \
12+
../Stack/stack.h ../Stack/stack.cpp \
13+
../Queue/Queue/queue.h ../Queue/Queue/queue.cpp
214

315
all: main
4-
main: graph.cpp graph.h ../List/list.h
16+
main: $(DEPEND)
517
g++ -std=c++11 -g $(INCLUDE) main.cpp -o main
618

719
clean:

Graph/graph.cpp

Lines changed: 310 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,14 @@
1-
#include "graph.h"
1+
#ifdef GRAPH_H
2+
3+
template<class DataType>
4+
void ptr_check(const DataType*& ptr)
5+
{
6+
if(!ptr)
7+
{
8+
cerr << "Failed to allocate memory!" << endl;
9+
exit(-1);
10+
}
11+
}
212

313
// Graph information
414
template<class VDataType, class EDataType>
@@ -401,4 +411,302 @@ void DiGraph<VDataType, EDataType>::write(const string& name, bool show_weight,
401411
file.close();
402412

403413
system((layout + " -Tpdf Figures/" + name + ".dot -o Figures/" + name).data());
404-
}
414+
}
415+
416+
template<class VDataType, class EDataType>
417+
void DiGraph<VDataType, EDataType>::reset()
418+
{
419+
for(auto it_vertex = vertex_list.begin(); it_vertex != vertex_list.end(); it_vertex++)
420+
{
421+
it_vertex->status = Vertex<VDataType, EDataType>::UNDISCOVERED;
422+
it_vertex->discover_time = 0;
423+
it_vertex->finish_time = 0;
424+
it_vertex->got = false;
425+
426+
for(auto it_edge = it_vertex->adjacency_list.begin();
427+
it_edge != it_vertex->adjacency_list.end(); it_edge++)
428+
{
429+
it_edge->type = Edge<VDataType, EDataType>::UNDETERMINED;
430+
}
431+
}
432+
}
433+
434+
template<class VDataType, class EDataType>
435+
Tree<VDataType*>& DiGraph<VDataType, EDataType>::bfs(Vertex<VDataType, EDataType>* vertex)
436+
{
437+
Tree<VDataType*>* ptr_tree = new Tree<VDataType*>;
438+
auto tree_node = ptr_tree->insert_root(&(vertex->_data));
439+
440+
Queue< Vertex<VDataType, EDataType>* > queue_vertex;
441+
Queue< typename Tree<VDataType*>::Node* > queue_node;
442+
queue_vertex.push(vertex);
443+
queue_node.push(tree_node);
444+
445+
while(!queue_vertex.empty())
446+
{
447+
vertex = queue_vertex.pop();
448+
tree_node = queue_node.pop();
449+
for(auto it_edge = vertex->adjacency_list.begin();
450+
it_edge != vertex->adjacency_list.end(); it_edge++)
451+
{
452+
if(Vertex<VDataType, EDataType>::UNDISCOVERED == it_edge->_ptr_vertex_to->status)
453+
{
454+
it_edge->_ptr_vertex_to->status = Vertex<VDataType, EDataType>::DISCOVERED;
455+
queue_vertex.push(it_edge->_ptr_vertex_to);
456+
queue_node.push( ptr_tree->append_child(tree_node, &(it_edge->_ptr_vertex_to->_data)) );
457+
it_edge->type = Edge<VDataType, EDataType>::TREE;
458+
}
459+
else
460+
{
461+
it_edge->type = Edge<VDataType, EDataType>::CROSS;
462+
}
463+
}
464+
vertex->status = Vertex<VDataType, EDataType>::VISITED;
465+
}
466+
467+
return *ptr_tree;
468+
}
469+
470+
template<class VDataType, class EDataType>
471+
Forest<VDataType*>& DiGraph<VDataType, EDataType>::BFS(Vertex<VDataType, EDataType>* vertex)
472+
{
473+
Forest<VDataType*>* ptr_forest = new Forest<VDataType*>;
474+
ptr_check(ptr_forest);
475+
476+
if(empty())
477+
{
478+
cout << "Warning in 'Forest<VDataType*>& DiGraph<VDataType, EDataType>::BFS(Vertex<VDataType, EDataType>* vertex)'" << endl
479+
<< "Current Graph is empty. Return an empty tree." << endl;
480+
return *ptr_forest;
481+
}
482+
483+
if(!exist(vertex))
484+
{
485+
cout << "Warning in 'Forest<VDataType*>& DiGraph<VDataType, EDataType>::BFS(Vertex<VDataType, EDataType>* vertex)'" << endl
486+
<< "Current Graph dosen't has this vertex. Return an empty tree." << endl;
487+
return *ptr_forest;
488+
}
489+
490+
reset();
491+
492+
typename List< Vertex<VDataType, EDataType> >::iterator it0 = vertex_list.locate(vertex_list.locate(vertex));
493+
auto it_vertex = it0;
494+
495+
do
496+
{
497+
if(Vertex<VDataType, EDataType>::UNDISCOVERED == it_vertex->status)
498+
{
499+
ptr_forest->push_back(bfs(it_vertex.ptr()));
500+
}
501+
502+
it_vertex++;
503+
if(it_vertex == vertex_list.end())
504+
{
505+
it_vertex = vertex_list.begin();
506+
}
507+
}
508+
while(it_vertex != it0);
509+
510+
return *ptr_forest;
511+
}
512+
513+
template<class VDataType, class EDataType>
514+
Forest<VDataType*>& DiGraph<VDataType, EDataType>::BFS()
515+
{
516+
return BFS(&vertex_list[0]);
517+
}
518+
519+
template<class VDataType, class EDataType>
520+
void DiGraph<VDataType, EDataType>::dfs(Vertex<VDataType, EDataType>* vertex, int& clock)
521+
{
522+
vertex->status = Vertex<VDataType, EDataType>::DISCOVERED;
523+
vertex->discover_time = ++clock;
524+
for(auto it_edge = vertex->adjacency_list.begin();
525+
it_edge != vertex->adjacency_list.end(); it_edge++)
526+
{
527+
switch(it_edge->_ptr_vertex_to->status)
528+
{
529+
case Vertex<VDataType, EDataType>::UNDISCOVERED:
530+
{
531+
it_edge->_ptr_vertex_to->discover_time = ++clock;
532+
it_edge->type = Edge<VDataType, EDataType>::TREE;
533+
dfs(it_edge->_ptr_vertex_to, clock);
534+
535+
break;
536+
}
537+
538+
case Vertex<VDataType, EDataType>::DISCOVERED:
539+
{
540+
it_edge->type = Edge<VDataType, EDataType>::BACKWARD;
541+
break;
542+
}
543+
544+
default:
545+
{
546+
it_edge->type = vertex->discover_time < it_edge->_ptr_vertex_to->discover_time ?
547+
Edge<VDataType, EDataType>::FORWARD : Edge<VDataType, EDataType>::CROSS;
548+
}
549+
}
550+
}
551+
vertex->status = Vertex<VDataType, EDataType>::VISITED;
552+
vertex->finish_time = ++clock;
553+
}
554+
555+
template<class VDataType, class EDataType>
556+
Tree<VDataType*>& DiGraph<VDataType, EDataType>::get_tree(Vertex<VDataType, EDataType>* vertex)
557+
{
558+
Tree<VDataType*>* ptr_tree = new Tree<VDataType*>;
559+
ptr_check(ptr_tree);
560+
561+
if(empty())
562+
{
563+
cout << "Warning in 'Tree<VDataType*>& DiGraph<VDataType, EDataType>::get_tree(Vertex<VDataType, EDataType>* vertex)'" << endl
564+
<< "Current Graph is empty. Return an empty tree." << endl;
565+
return *ptr_tree;
566+
}
567+
568+
if(!exist(vertex))
569+
{
570+
cout << "Warning in 'Tree<VDataType*>& DiGraph<VDataType, EDataType>::get_tree(Vertex<VDataType, EDataType>* vertex)'" << endl
571+
<< "Current Graph dosen't has this vertex. Return an empty tree." << endl;
572+
return *ptr_tree;
573+
}
574+
575+
ptr_tree->insert_root(&(vertex->_data));
576+
Queue< Vertex<VDataType, EDataType>* > queue_vertex;
577+
Queue< typename Tree<VDataType*>::Node* > queue_node;
578+
queue_vertex.push(vertex);
579+
queue_node.push(ptr_tree->root());
580+
581+
while(!queue_vertex.empty())
582+
{
583+
auto ptr_vertex = queue_vertex.pop();
584+
ptr_vertex->got = true;
585+
auto ptr_node = queue_node.pop();
586+
for(auto it_edge = ptr_vertex->adjacency_list.begin();
587+
it_edge != ptr_vertex->adjacency_list.end(); it_edge++)
588+
{
589+
if(Edge<VDataType, EDataType>::TREE == it_edge->type)
590+
{
591+
queue_node.push( ptr_tree->append_child(ptr_node, &(it_edge->_ptr_vertex_to->_data)) );
592+
queue_vertex.push(it_edge->_ptr_vertex_to);
593+
}
594+
}
595+
}
596+
597+
return *ptr_tree;
598+
}
599+
600+
template<class VDataType, class EDataType>
601+
Tree<VDataType*>& DiGraph<VDataType, EDataType>::get_tree()
602+
{
603+
return get_tree(&vertex_list[0]);
604+
}
605+
606+
template<class VDataType, class EDataType>
607+
Forest<VDataType*>& DiGraph<VDataType, EDataType>::get_forest(Vertex<VDataType, EDataType>* vertex)
608+
{
609+
Forest<VDataType*>* ptr_forest = new Forest<VDataType*>;
610+
ptr_check(ptr_forest);
611+
612+
if(empty())
613+
{
614+
cout << "Warning in 'Forest<VDataType*>& DiGraph<VDataType, EDataType>::get_forest(Vertex<VDataType, EDataType>* vertex)'" << endl
615+
<< "Current Graph is empty. Return an empty tree." << endl;
616+
return *ptr_forest;
617+
}
618+
619+
if(!exist(vertex))
620+
{
621+
cout << "Warning in 'Forest<VDataType*>& DiGraph<VDataType, EDataType>::get_forest(Vertex<VDataType, EDataType>* vertex)'" << endl
622+
<< "Current Graph dosen't has this vertex. Return an empty tree." << endl;
623+
return *ptr_forest;
624+
}
625+
626+
auto it0 = vertex_list.locate(vertex_list.locate(vertex));
627+
auto it_vertex = it0;
628+
629+
do
630+
{
631+
Tree<VDataType*> tree;
632+
if(!(it_vertex->got))
633+
{
634+
tree = get_tree(it_vertex.ptr());
635+
ptr_forest->push_back(tree);
636+
}
637+
638+
it_vertex++;
639+
if(it_vertex == vertex_list.end())
640+
{
641+
it_vertex = vertex_list.begin();
642+
}
643+
}
644+
while(it_vertex != it0);
645+
646+
for(it_vertex = vertex_list.begin(); it_vertex != vertex_list.end(); it_vertex++)
647+
{
648+
it_vertex->got = false;
649+
}
650+
651+
return *ptr_forest;
652+
}
653+
654+
template<class VDataType, class EDataType>
655+
Forest<VDataType*>& DiGraph<VDataType, EDataType>::get_forest()
656+
{
657+
return get_forest(&vertex_list[0]);
658+
}
659+
660+
template<class VDataType, class EDataType>
661+
Forest<VDataType*>& DiGraph<VDataType, EDataType>::DFS(Vertex<VDataType, EDataType>* vertex)
662+
{
663+
Forest<VDataType*>* ptr_forest = new Forest<VDataType*>;
664+
ptr_check(ptr_forest);
665+
666+
if(empty())
667+
{
668+
cout << "Warning in 'Forest<VDataType*>& DiGraph<VDataType, EDataType>::DFS(Vertex<VDataType, EDataType>* vertex)'" << endl
669+
<< "Current Graph is empty. Return an empty tree." << endl;
670+
return *ptr_forest;
671+
}
672+
673+
if(!exist(vertex))
674+
{
675+
cout << "Warning in 'Forest<VDataType*>& DiGraph<VDataType, EDataType>::DFS(Vertex<VDataType, EDataType>* vertex)'" << endl
676+
<< "Current Graph dosen't has this vertex. Return an empty tree." << endl;
677+
return *ptr_forest;
678+
}
679+
680+
reset();
681+
682+
int clock = 0;
683+
typename List< Vertex<VDataType, EDataType> >::iterator it0 = vertex_list.locate(vertex_list.locate(vertex));
684+
auto it_vertex = it0;
685+
686+
do
687+
{
688+
if(Vertex<VDataType, EDataType>::UNDISCOVERED == it_vertex->status)
689+
{
690+
dfs(it_vertex.ptr(), clock);
691+
Tree<VDataType*> tree = get_tree(it_vertex.ptr());
692+
ptr_forest->push_back(tree);
693+
}
694+
695+
it_vertex++;
696+
if(it_vertex == vertex_list.end())
697+
{
698+
it_vertex = vertex_list.begin();
699+
}
700+
}
701+
while(it_vertex != it0);
702+
703+
return *ptr_forest;
704+
}
705+
706+
template<class VDataType, class EDataType>
707+
Forest<VDataType*>& DiGraph<VDataType, EDataType>::DFS()
708+
{
709+
return DFS(&vertex_list[0]);
710+
}
711+
712+
#endif

0 commit comments

Comments
 (0)