위상 정렬(Topological Sort)은 노드 A에서 노드 B로 가는 간선이 있다면 노드 A를 노드 B보다 앞으로 하여 정렬하는 것을 의미한다.
그리고, 위상 정렬이 가능한 그래프는 사이클이 없는 방향 그래프(DAG)이다.
위상 정렬은 왜 하는 것일까?
위상 정렬을 하는 이유는 위상 정렬을 했을 때 문제가 쉬워지는 경우가 많기 때문이다.
위상 정렬이 쓰이는 경우를 예시를 통해서 살펴보자.
다음과 같이 선후수 과목의 정보가 주어졌을 때, 어떠한 과목 순으로 들어야 하는지를 구해보자. ㆍ과목 B는 과목 A를 들어야 수강할 수 있다. ㆍ과목 B는 과목 C를 들어야 수강할 수 있다. ㆍ과목 D는 과목 C를 들어야 수강할 수 있다.
이 상황을 그래프로 나타내면 다음과 같다.
위 그래프는 DAG이므로, 이를 위상 정렬을 하는 것만으로도 어떠한 과목 순으로 들어야 하는지 알 수 있다. 위상 정렬의 결과는 여러 가지 경우가 나올 수 있으며, 위 그래프에 대한 위상 정렬도 다음과 같이 여러 개다. ㆍA, C, B, D ㆍA, C, D, B ㆍC, A, B, D ㆍC, A, D, B ㆍC, D, A, B
이제 위상 정렬을 구현하는 법에 대해서 살펴보겠다.
만약, 다음과 같은 사이클이 없는 방향 그래프(DAG)가 주어지면 어떻게 위상 정렬을 할 수 있을까?
위상 정렬은 노드의 진입 차수를 이용하면 간단하게 구현할 수 있다.
노드의 진입 차수란 해당 노드를 가리키고 있는 간선의 개수를 의미함
그래프에서 진입 차수가 0인 노드부터 방문하며 방문을 한 노드는 자신이 가리키고 있는 노드의 진입 차수를 갱신해 준다.
이를 반복하면 위상 정렬의 순서대로 노드를 방문하게 되며 방문 순서가 위상 정렬의 결과가 된다.
위의 그래프에 대해서 위상 정렬을 수행하면 다음과 같은 과정이 순서대로 일어난다.
(각 노드에 파란색으로 표시된 숫자는 현재 해당 노드에 대한 진입차수를 의미한다.)
초기 상태노드 0을 방문노드 1을 방문노드 2를 방문
노드 3을 방문노드 4를 방문노드 5를 방문
위와 같이 위상 정렬을 수행하고 나면 결과는 0, 1, 2, 3, 4, 5 가 나오게 된다.
이를 코드로 구현하는 법은 초기 그래프에서 진입차수가 0인 노드들을 기준으로 방문을 진행하면 된다.
(in_degree는 진입차수를 저장하는 배열, candidate는 초기에 진입차수가 0인 노드를 저장하는 배열, result는 정렬 결과를 저장하는 배열이다.)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters