forked from aalhour/C-Sharp-Algorithms
-
Notifications
You must be signed in to change notification settings - Fork 0
/
ConnectedComponents.cs
73 lines (59 loc) · 2.34 KB
/
ConnectedComponents.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
/***
* Connected Components.
*
* Computes the connected components for undirected graphs.
*
* Provides:
* * Compute: Returns a list of lists of nodes. Each inner list represents a connected component of nodes.
*/
using System;
using System.Collections.Generic;
using DataStructures.Graphs;
namespace Algorithms.Graphs
{
public static class ConnectedComponents
{
/// <summary>
/// Private helper. Discovers a connected component and return from a source vertex in a graph.
/// </summary>
private static List<TVertex> _bfsConnectedComponent<TVertex>(IGraph<TVertex> graph, TVertex source, ref HashSet<TVertex> visited) where TVertex : IComparable<TVertex>
{
var component = new List<TVertex>();
var queue = new Queue<TVertex>();
queue.Enqueue(source);
while (queue.Count > 0)
{
var current = queue.Dequeue();
if (!visited.Contains(current))
{
component.Add(current);
visited.Add(current);
foreach (var adjacent in graph.Neighbours(current))
if (!visited.Contains(adjacent))
queue.Enqueue(adjacent);
}
}
return component;
}
/// <summary>
/// Return the the connected components in graph as list of lists of nodes. Each list represents a connected component.
/// </summary>
public static List<List<TVertex>> Compute<TVertex>(IGraph<TVertex> Graph) where TVertex : IComparable<TVertex>
{
var components = new List<List<TVertex>>();
var visited = new HashSet<TVertex>();
// Validate the graph parameter
if (Graph == null)
throw new ArgumentNullException();
if (Graph.IsDirected == true)
throw new NotSupportedException("Directed Graphs are not supported.");
if(Graph.VerticesCount == 0)
return components;
// Get connected components using BFS
foreach(var vertex in Graph.Vertices)
if(!visited.Contains(vertex))
components.Add(_bfsConnectedComponent<TVertex>(Graph, vertex, ref visited));
return components;
}
}
}