@@ -3555,4 +3555,130 @@ public object VisitUsingExpression(UsingExpressionAst usingExpressionAst)
3555
3555
return null ;
3556
3556
}
3557
3557
}
3558
+
3559
+ /// Class to represent a directed graph
3560
+ public class Digraph < T >
3561
+ {
3562
+ public int NumVertices
3563
+ {
3564
+ get { return graph . Count ; }
3565
+ }
3566
+
3567
+ private List < List < int > > graph ;
3568
+ private Dictionary < T , int > vertexIndexMap ;
3569
+
3570
+
3571
+ private int GetIndex ( T vertex )
3572
+ {
3573
+ int idx ;
3574
+ return vertexIndexMap . TryGetValue ( vertex , out idx ) ? idx : - 1 ;
3575
+ }
3576
+
3577
+ public IEnumerable < T > GetNeighbors ( T vertex )
3578
+ {
3579
+ ValidateVertexArgument ( vertex ) ;
3580
+ var idx = GetIndex ( vertex ) ;
3581
+ var idxVertexMap = vertexIndexMap . ToDictionary ( x => x . Value , x => x . Key ) ;
3582
+ foreach ( var neighbor in graph [ idx ] )
3583
+ {
3584
+ yield return idxVertexMap [ neighbor ] ;
3585
+ }
3586
+ }
3587
+
3588
+ public int GetNumNeighbors ( T vertex )
3589
+ {
3590
+ ValidateVertexArgument ( vertex ) ;
3591
+ return graph [ GetIndex ( vertex ) ] . Count ;
3592
+ }
3593
+
3594
+ public Digraph ( )
3595
+ {
3596
+ graph = new List < List < int > > ( ) ;
3597
+ vertexIndexMap = new Dictionary < T , int > ( ) ;
3598
+ }
3599
+
3600
+ public void AddVertex ( T vertex )
3601
+ {
3602
+ if ( vertex == null )
3603
+ {
3604
+ throw new ArgumentNullException ( "vertex" ) ;
3605
+ }
3606
+
3607
+ if ( GetIndex ( vertex ) != - 1 )
3608
+ {
3609
+ throw new ArgumentException ( "Vertex already present! Cannot add it to the Digraph" , "vertex" ) ;
3610
+ }
3611
+
3612
+ vertexIndexMap . Add ( vertex , graph . Count ) ;
3613
+ graph . Add ( new List < int > ( ) ) ;
3614
+ }
3615
+
3616
+ public void AddEdge ( T fromVertex , T toVertex )
3617
+ {
3618
+ ValidateVertexArgument ( fromVertex ) ;
3619
+ ValidateVertexArgument ( toVertex ) ;
3620
+
3621
+ var toIdx = GetIndex ( toVertex ) ;
3622
+ var fromVertexList = graph [ GetIndex ( fromVertex ) ] ;
3623
+ if ( ! fromVertexList . Contains ( toIdx ) )
3624
+ {
3625
+ fromVertexList . Add ( toIdx ) ;
3626
+ }
3627
+ }
3628
+
3629
+ public bool IsConnected ( T vertex1 , T vertex2 )
3630
+ {
3631
+ ValidateVertexArgument ( vertex1 ) ;
3632
+ ValidateVertexArgument ( vertex2 ) ;
3633
+ var visited = new bool [ graph . Count ] ;
3634
+ return IsConnected ( GetIndex ( vertex1 ) , GetIndex ( vertex2 ) , ref visited ) ;
3635
+ }
3636
+
3637
+ private bool IsConnected ( int fromIdx , int toIdx , ref bool [ ] visited )
3638
+ {
3639
+ visited [ fromIdx ] = true ;
3640
+ if ( fromIdx == toIdx )
3641
+ {
3642
+ return true ;
3643
+ }
3644
+
3645
+ bool isConnected = false ;
3646
+ foreach ( var vertexIdx in graph [ fromIdx ] )
3647
+ {
3648
+ if ( ! visited [ vertexIdx ] )
3649
+ {
3650
+ isConnected |= IsConnected ( vertexIdx , toIdx , ref visited ) ;
3651
+ }
3652
+
3653
+ if ( isConnected ) // no need to search further
3654
+ {
3655
+ break ;
3656
+ }
3657
+ }
3658
+
3659
+ return isConnected ;
3660
+ }
3661
+
3662
+ private void ValidateNotNull ( T vertex )
3663
+ {
3664
+ if ( vertex == null )
3665
+ {
3666
+ throw new ArgumentNullException ( "vertex" ) ;
3667
+ }
3668
+ }
3669
+
3670
+ private void ValidateVertexPresence ( T vertex )
3671
+ {
3672
+ if ( GetIndex ( vertex ) == - 1 )
3673
+ {
3674
+ throw new ArgumentOutOfRangeException ( "vertex not present in the Digraph." , "vertex" ) ;
3675
+ }
3676
+ }
3677
+
3678
+ private void ValidateVertexArgument ( T vertex )
3679
+ {
3680
+ ValidateNotNull ( vertex ) ;
3681
+ ValidateVertexPresence ( vertex ) ;
3682
+ }
3683
+ }
3558
3684
}
0 commit comments