@@ -621,87 +621,63 @@ class Graph<T> {
621
621
return components ;
622
622
} ;
623
623
624
- // dfs iterative
625
- // Returns: a list of all verteces found (in the order of dequeue)
626
- // the parent of each visited vertex
627
- // all visited verteces
628
- dfs = ( s : T ) => {
629
- // popped stack order
630
- const result : Array < T > = new Array ( ) ;
631
- const parents : Map < T , null | T > = new Map ( ) ;
632
- // a node is visited when it is popped from the stack
633
- const visited : Map < T , boolean > = new Map ( ) ;
634
- const stack = new Stack ( ) ;
635
- stack . push ( s ) ;
636
- parents . set ( s , null ) ;
637
- let v : Node ;
638
-
639
- while ( stack . size !== 0 ) {
640
- // take from the top of the stack
641
- v = stack . pop ( ) ! ;
642
- if ( ! visited . get ( v . key ) ) {
643
- result . push ( v . key ) ;
644
- visited . set ( v . key , true ) ;
645
- }
646
- this . list . get ( v . key ) ! . forEach ( ( u ) => {
647
- if ( ! visited . get ( u . node ) ) {
648
- parents . set ( u . node , v . key ) ;
649
- stack . push ( u . node ) ;
650
- }
651
- } ) ;
652
- }
653
- return {
654
- result,
655
- parents,
656
- visited,
657
- } ;
658
- } ;
659
-
660
624
// dfs recursive
661
- // Returns: a list of all verteces found (in the order of dequeue)
662
- // the parent of each visited vertex
663
- // all visited verteces
664
- dfsRec = (
625
+ dfs = (
665
626
s : T ,
666
- visited : Map < T , boolean > = new Map ( ) ,
627
+ // white: unvisited node (not used in this implementation)
628
+ // first time we see a node it is not in the map
629
+ // gray: visited node, but not finish (all neighbours also visited)
630
+ // black: finished node
631
+ color : Map < T , string > = new Map ( ) ,
667
632
labeledOrder : Map < T , number | null > = new Map ( ) ,
668
- finish : Array < T > = new Array ( )
633
+ finish : Array < T > = new Array ( ) ,
634
+ parents : Map < T , T > = new Map ( ) ,
635
+ cycle = false
669
636
) => {
670
637
// mark s as visited
671
- visited . set ( s , true ) ;
638
+ color . set ( s , "gray" ) ;
672
639
// for every edge of s
673
640
this . list . get ( s ) ! . forEach ( ( u ) => {
674
- if ( ! visited . get ( u . node ) ) {
641
+ if ( ! color . get ( u . node ) ) {
642
+ // set u as a child of s
643
+ parents . set ( u . node , s ) ;
675
644
// recursive call
676
- this . dfsRec ( u . node , visited , labeledOrder , finish ) ;
645
+ this . dfs ( u . node , color , labeledOrder , finish , parents , cycle ) ;
646
+ } else if ( color . get ( u . node ) === "gray" ) {
647
+ // back edge:
648
+ // u is an ancestor of s (i.e., there is some path u -> s, and now we found an edge s -> u)
649
+ // forming a cycle
650
+ cycle = true ;
677
651
}
678
652
} ) ;
679
- if ( ! labeledOrder . get ( s ) ) {
680
- labeledOrder . set ( s , this . currentLabel ) ;
681
- this . currentLabel ! -- ;
682
- finish . push ( s ) ;
683
- }
653
+ // all neighbours visited => finished!
654
+ labeledOrder . set ( s , this . currentLabel ) ;
655
+ color . set ( s , "black" ) ;
656
+ this . currentLabel ! -- ;
657
+ finish . push ( s ) ;
684
658
return {
685
659
labeledOrder,
686
- visited ,
660
+ color ,
687
661
finish,
662
+ parents,
663
+ cycle,
688
664
} ;
689
665
} ;
690
666
691
667
// Returns the labeled order and finish order
692
668
// Does not work for cycled graphs, only DAGs
693
669
topologicalSort ( ) {
694
670
const labeledOrder : Map < T , number | null > = new Map ( ) ;
695
- const visited : Map < T , boolean > = new Map ( ) ;
671
+ const color : Map < T , string > = new Map ( ) ;
696
672
const finish : Array < T > = new Array ( ) ;
697
673
// to keep track of ordering
698
674
this . currentLabel = this . list . size ;
699
675
for ( let [ u ] of this . list ) {
700
- if ( ! visited . get ( u ) ) {
701
- const r = this . dfsRec ( u ) ;
676
+ if ( ! color . get ( u ) ) {
677
+ const r = this . dfs ( u ) ;
702
678
// update values
703
- r . visited . forEach ( ( value , key ) => {
704
- visited . set ( key , value ) ;
679
+ r . color . forEach ( ( value , key ) => {
680
+ color . set ( key , value ) ;
705
681
} ) ;
706
682
r . labeledOrder . forEach ( ( value , key ) => {
707
683
labeledOrder . set ( key , value ) ;
@@ -720,20 +696,22 @@ class Graph<T> {
720
696
// finish order
721
697
if ( gRerv === false ) return false ;
722
698
const { finish } = gRerv . topologicalSort ( ) ;
723
- const visited : Map < T , boolean > = new Map ( ) ;
699
+ const color : Map < T , string > = new Map ( ) ;
724
700
// the vertex who calls dfs (maps leader's vertex key to the size of the Strong Component)
725
701
const leader : Map < T , number > = new Map ( ) ;
726
702
let u , r ;
727
- for ( let i = 0 ; i < finish . length ; i ++ ) {
703
+ // for (let i = 0; i < finish.length; i++) {
704
+ for ( let i = finish . length - 1 ; i > 0 ; i -- ) {
728
705
u = finish [ i ] ;
729
- if ( ! visited . get ( u ) ) {
730
- r = this . dfs ( u ) ;
706
+ if ( ! color . get ( u ) ) {
707
+ // r = this.dfs(u);
708
+ r = this . dfs ( u , color ) ;
731
709
// update visited
732
- r . visited . forEach ( ( value , key ) => {
733
- visited . set ( key , value ) ;
710
+ r . color . forEach ( ( value , key ) => {
711
+ color . set ( key , value ) ;
734
712
} ) ;
735
713
// all verteces visited have u as leader
736
- leader . set ( u , r . result . length ) ;
714
+ leader . set ( u , r . finish . length ) ;
737
715
}
738
716
}
739
717
return leader ;
0 commit comments