■ 너비 우선 탐색하는 방법을 보여준다. (Breadth-First Search)
▶ Graph.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 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
using System; using System.Collections.Generic; namespace TestProject { /// <summary> /// 그래프 /// </summary> /// <typeparam name="T">항목 타입</typeparam> public class Graph<T> { //////////////////////////////////////////////////////////////////////////////////////////////////// Property ////////////////////////////////////////////////////////////////////////////////////////// Public #region 이웃 딕셔너리 - AdjacencyDictionary /// <summary> /// 이웃 딕셔너리 /// </summary> public Dictionary<T, HashSet<T>> AdjacencyDictionary { get; } = new Dictionary<T, HashSet<T>>(); #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor ////////////////////////////////////////////////////////////////////////////////////////// Public #region 생성자 - Graph() /// <summary> /// 생성자 /// </summary> public Graph() { } #endregion #region 생성자 - Graph(vertexEnumerable, edgeEnumerable) /// <summary> /// 생성자 /// </summary> /// <param name="vertexEnumerable">정점 열거형</param> /// <param name="edgeEnumerable">엣지 열거형</param> public Graph(IEnumerable<T> vertexEnumerable, IEnumerable<Tuple<T,T>> edgeEnumerable) { foreach(T vertex in vertexEnumerable) { AddVertex(vertex); } foreach(Tuple<T, T> edge in edgeEnumerable) { AddEdge(edge); } } #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Public #region 정점 추가하기 - AddVertex(vertex) /// <summary> /// 정점 추가하기 /// </summary> /// <param name="vertex">정점</param> public void AddVertex(T vertex) { AdjacencyDictionary[vertex] = new HashSet<T>(); } #endregion #region 엣지 추가하기 - AddEdge(edge) /// <summary> /// 엣지 추가하기 /// </summary> /// <param name="edge">엣지</param> public void AddEdge(Tuple<T,T> edge) { if(AdjacencyDictionary.ContainsKey(edge.Item1) && AdjacencyDictionary.ContainsKey(edge.Item2)) { AdjacencyDictionary[edge.Item1].Add(edge.Item2); AdjacencyDictionary[edge.Item2].Add(edge.Item1); } } #endregion } } |
▶ GraphHelper.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 |
using System.Collections.Generic; namespace TestProject { /// <summary> /// 그래프 헬퍼 /// </summary> public static class GraphHelper { //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Static //////////////////////////////////////////////////////////////////////////////// Public #region 너비 우선 탐색하기 - BreadthFirstSearch<T>(graph, startItem) /// <summary> /// 너비 우선 탐색하기 /// </summary> /// <typeparam name="T">항목 타입</typeparam> /// <param name="graph">그래프</param> /// <param name="startItem">시작 항목</param> /// <returns>너비 우선 탐색 결과</returns> public static HashSet<T> BreadthFirstSearch<T>(Graph<T> graph, T startItem) { HashSet<T> visitedVertexHashSet = new HashSet<T>(); if(!graph.AdjacencyDictionary.ContainsKey(startItem)) { return visitedVertexHashSet; } Queue<T> queue = new Queue<T>(); queue.Enqueue(startItem); while(queue.Count > 0) { T vertex = queue.Dequeue(); if(visitedVertexHashSet.Contains(vertex)) { continue; } visitedVertexHashSet.Add(vertex); foreach(T neighborVertex in graph.AdjacencyDictionary[vertex]) { if(!visitedVertexHashSet.Contains(neighborVertex)) { queue.Enqueue(neighborVertex); } } } return visitedVertexHashSet; } #endregion } } |
▶ Program.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 |
using System; using System.Collections.Generic; namespace TestProject { /// <summary> /// 프로그램 /// </summary> class Program { //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Static //////////////////////////////////////////////////////////////////////////////// Private #region 프로그램 시작하기 - Main() /// <summary> /// 프로그램 시작하기 /// </summary> private static void Main() { Console.Title = "너비 우선 탐색하기 (Breadth-First Search)"; List<Student> vertexList = Student.GetList(10); List<Tuple<Student, Student>> edgeList = new List<Tuple<Student, Student>> { Tuple.Create(vertexList[0], vertexList[1]), Tuple.Create(vertexList[0], vertexList[2]), Tuple.Create(vertexList[1], vertexList[3]), Tuple.Create(vertexList[2], vertexList[4]), Tuple.Create(vertexList[2], vertexList[5]), Tuple.Create(vertexList[3], vertexList[6]), Tuple.Create(vertexList[4], vertexList[6]), Tuple.Create(vertexList[4], vertexList[7]), Tuple.Create(vertexList[4], vertexList[5]), Tuple.Create(vertexList[7], vertexList[8]), Tuple.Create(vertexList[8], vertexList[9]) }; Graph<Student> graph = new Graph<Student>(vertexList, edgeList); HashSet<Student> vertexHashSet = GraphHelper.BreadthFirstSearch<Student>(graph, vertexList[0]); foreach(Student vertex in vertexHashSet) { Console.WriteLine("학번 : {0}, 성명 : {1}", vertex.ID, vertex.Name); } } #endregion } } |