@@ -3556,70 +3556,107 @@ public object VisitUsingExpression(UsingExpressionAst usingExpressionAst)
35563556 }
35573557 }
35583558
3559- /// Class to represent a directed graph
35603559 /// Class to represent a directed graph
35613560 public class Digraph < T >
35623561 {
3563- public int NumVertices
3564- {
3565- get { return graph . Count ; }
3566- }
3567-
35683562 private List < List < int > > graph ;
35693563 private Dictionary < T , int > vertexIndexMap ;
35703564
3571-
3572- private int GetIndex ( T vertex )
3565+ /// <summary>
3566+ /// Public constructor
3567+ /// </summary>
3568+ public Digraph ( )
35733569 {
3574- int idx ;
3575- return vertexIndexMap . TryGetValue ( vertex , out idx ) ? idx : - 1 ;
3570+ graph = new List < List < int > > ( ) ;
3571+ vertexIndexMap = new Dictionary < T , int > ( ) ;
35763572 }
35773573
3578- public IEnumerable < T > GetNeighbors ( T vertex )
3574+ /// <summary>
3575+ /// Construct digraph with an EqualityComparer used for comparing type T
3576+ /// </summary>
3577+ /// <param name="equalityComparer"></param>
3578+ public Digraph ( IEqualityComparer < T > equalityComparer ) : this ( )
35793579 {
3580- ValidateVertexArgument ( vertex ) ;
3581- var idx = GetIndex ( vertex ) ;
3582- var idxVertexMap = vertexIndexMap . ToDictionary ( x => x . Value , x => x . Key ) ;
3583- foreach ( var neighbor in graph [ idx ] )
3580+ if ( equalityComparer == null )
35843581 {
3585- yield return idxVertexMap [ neighbor ] ;
3582+ throw new ArgumentNullException ( "equalityComparer" ) ;
35863583 }
3584+
3585+ vertexIndexMap = new Dictionary < T , int > ( equalityComparer ) ;
35873586 }
35883587
3588+ /// <summary>
3589+ /// Return the number of vertices in the graph
3590+ /// </summary>
3591+ public int NumVertices
3592+ {
3593+ get { return graph . Count ; }
3594+ }
3595+
3596+ /// <summary>
3597+ /// Return an enumerator over the vertices in the graph
3598+ /// </summary>
35893599 public IEnumerable < T > GetVertices ( )
35903600 {
35913601 return vertexIndexMap . Keys ;
35923602 }
35933603
3604+ /// <summary>
3605+ /// Check if the given vertex is part of the graph.
3606+ ///
3607+ /// If the vertex is null, it will throw an ArgumentNullException.
3608+ /// If the vertex is non-null but not present in the graph, it will throw an ArgumentOutOfRangeException
3609+ /// </summary>
3610+ /// <param name="vertex"></param>
3611+ /// <returns>True if the graph contains the vertex, otherwise false</returns>
35943612 public bool ContainsVertex ( T vertex )
35953613 {
35963614 return vertexIndexMap . Keys . Contains ( vertex ) ;
35973615 }
35983616
3599- public int GetNumNeighbors ( T vertex )
3617+ /// <summary>
3618+ /// Get the neighbors of a given vertex
3619+ ///
3620+ /// If the vertex is null, it will throw an ArgumentNullException.
3621+ /// If the vertex is non-null but not present in the graph, it will throw an ArgumentOutOfRangeException
3622+ /// </summary>
3623+ /// <param name="vertex"></param>
3624+ /// <returns>An enumerator over the neighbors of the vertex</returns>
3625+ public IEnumerable < T > GetNeighbors ( T vertex )
36003626 {
36013627 ValidateVertexArgument ( vertex ) ;
3602- return graph [ GetIndex ( vertex ) ] . Count ;
3603- }
3604-
3605- public Digraph ( )
3606- {
3607- graph = new List < List < int > > ( ) ;
3608- vertexIndexMap = new Dictionary < T , int > ( ) ;
3628+ var idx = GetIndex ( vertex ) ;
3629+ var idxVertexMap = vertexIndexMap . ToDictionary ( x => x . Value , x => x . Key ) ;
3630+ foreach ( var neighbor in graph [ idx ] )
3631+ {
3632+ yield return idxVertexMap [ neighbor ] ;
3633+ }
36093634 }
36103635
3611- public Digraph ( IEqualityComparer < T > comparer ) : this ( )
3636+ /// <summary>
3637+ /// Gets the number of neighbors of the given vertex
3638+ ///
3639+ /// If the vertex is null, it will throw an ArgumentNullException.
3640+ /// If the vertex is non-null but not present in the graph, it will throw an ArgumentOutOfRangeException
3641+ /// </summary>
3642+ /// <param name="vertex"></param>
3643+ /// <returns></returns>
3644+ public int GetNumNeighbors ( T vertex )
36123645 {
3613- vertexIndexMap = new Dictionary < T , int > ( comparer ) ;
3646+ ValidateVertexArgument ( vertex ) ;
3647+ return graph [ GetIndex ( vertex ) ] . Count ;
36143648 }
36153649
3650+ /// <summary>
3651+ /// Add a vertex to the graph
3652+ ///
3653+ /// If the vertex is null, it will throw an ArgumentNullException.
3654+ /// If the vertex is non-null but already present in the graph, it will throw an ArgumentException
3655+ /// </summary>
3656+ /// <param name="vertex"></param>
36163657 public void AddVertex ( T vertex )
36173658 {
3618- if ( vertex == null )
3619- {
3620- throw new ArgumentNullException ( "vertex" ) ;
3621- }
3622-
3659+ ValidateNotNull ( vertex ) ;
36233660 if ( GetIndex ( vertex ) != - 1 )
36243661 {
36253662 throw new ArgumentException ( "Vertex already present! Cannot add it to the Digraph" , "vertex" ) ;
@@ -3629,6 +3666,14 @@ public void AddVertex(T vertex)
36293666 graph . Add ( new List < int > ( ) ) ;
36303667 }
36313668
3669+ /// <summary>
3670+ /// Add an edge from one vertex to another
3671+ ///
3672+ /// If any input vertex is null, it will throw an ArgumentNullException
3673+ /// If an edge is already present between the given vertices, it will throw an ArgumentException
3674+ /// </summary>
3675+ /// <param name="fromVertex"></param>
3676+ /// <param name="toVertex"></param>
36323677 public void AddEdge ( T fromVertex , T toVertex )
36333678 {
36343679 ValidateVertexArgument ( fromVertex ) ;
@@ -3649,14 +3694,28 @@ public void AddEdge(T fromVertex, T toVertex)
36493694 }
36503695 }
36513696
3697+ /// <summary>
3698+ /// Checks if a vertex is connected to another vertex within the graph
3699+ /// </summary>
3700+ /// <param name="vertex1"></param>
3701+ /// <param name="vertex2"></param>
3702+ /// <returns></returns>
36523703 public bool IsConnected ( T vertex1 , T vertex2 )
36533704 {
36543705 ValidateVertexArgument ( vertex1 ) ;
36553706 ValidateVertexArgument ( vertex2 ) ;
3707+
36563708 var visited = new bool [ graph . Count ] ;
36573709 return IsConnected ( GetIndex ( vertex1 ) , GetIndex ( vertex2 ) , ref visited ) ;
36583710 }
36593711
3712+ /// <summary>
3713+ /// Check if two vertices are connected
3714+ /// </summary>
3715+ /// <param name="fromIdx">Origin vertex</param>
3716+ /// <param name="toIdx">Destination vertex</param>
3717+ /// <param name="visited">A boolean array indicating whether a vertex has been visited or not</param>
3718+ /// <returns>True if the vertices are conneted, otherwise false</returns>
36603719 private bool IsConnected ( int fromIdx , int toIdx , ref bool [ ] visited )
36613720 {
36623721 visited [ fromIdx ] = true ;
@@ -3682,6 +3741,9 @@ private bool IsConnected(int fromIdx, int toIdx, ref bool[] visited)
36823741 return isConnected ;
36833742 }
36843743
3744+ /// <summary>
3745+ /// Throw an ArgumentNullException if vertex is null
3746+ /// </summary>
36853747 private void ValidateNotNull ( T vertex )
36863748 {
36873749 if ( vertex == null )
@@ -3690,6 +3752,9 @@ private void ValidateNotNull(T vertex)
36903752 }
36913753 }
36923754
3755+ /// <summary>
3756+ /// Throw an ArgumentOutOfRangeException if vertex is not present in the graph
3757+ /// </summary>
36933758 private void ValidateVertexPresence ( T vertex )
36943759 {
36953760 if ( GetIndex ( vertex ) == - 1 )
@@ -3698,10 +3763,23 @@ private void ValidateVertexPresence(T vertex)
36983763 }
36993764 }
37003765
3766+ /// <summary>
3767+ /// Throw exception if vertex is null or not present in graph
3768+ /// </summary>
37013769 private void ValidateVertexArgument ( T vertex )
37023770 {
37033771 ValidateNotNull ( vertex ) ;
37043772 ValidateVertexPresence ( vertex ) ;
37053773 }
3774+
3775+ /// <summary>
3776+ /// Get the index of the vertex in the graph array
3777+ /// </summary>
3778+ private int GetIndex ( T vertex )
3779+ {
3780+ int idx ;
3781+ return vertexIndexMap . TryGetValue ( vertex , out idx ) ? idx : - 1 ;
3782+ }
3783+
37063784 }
37073785}
0 commit comments