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
+ }
2
12
3
13
// Graph information
4
14
template <class VDataType , class EDataType >
@@ -401,4 +411,302 @@ void DiGraph<VDataType, EDataType>::write(const string& name, bool show_weight,
401
411
file.close ();
402
412
403
413
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