순서가 정해져 있는 일련의 작업을 차례대로 수행해야 할 때 사용할 수 있는 알고리즘.
ex) 선수과목을 고려한 학습 순서
조금 더 이론적인 설명은
`사이클이 없는 방향 그래프의 모든 노드를 '방향성에 거스르지 않도록 순서대로 나열하는 것' 을 의미한다.
다음 예시를 보자.
그림과 같이 3개의 과목이 있다고 가정하면,
세 과목을 모두 듣기 위해서 자료구조 → 알고리즘 → 고급 알고리즘
순서로 과목을 들어야 한다.
만약 자료구조 → 고급 알고리즘 → 알고리즘 (X)
순서로 과목을 듣는다고 하면, 해당 순서는 올바른 순서가 아니다.
위상 정렬 알고리즘을 이해하기 위해서는 먼저 진입차수와 진출차수에 대해 알아야한다.
큐를 이용하는 위상 정렬 알고리즘의 동작 과정
은 다음과 같다.
즉, 각 노드가 큐에 들어온 순서가 위상정렬을 수행한 결과 이다!
그림과 함께 다시 보자. (그림 출처 : 이코테)
위 그림은 위상 정렬을 수행할 그래프이다. 이때 위상 정렬을 수행할 수 있는 그래프는 사이클이 없는 방향 그래프 (DAG) 이여야 한다!
[step 0] 진입차수가 0인 모든 노드를 큐에 삽입. 현재 1번 노드의 진입차수만 0이므로 큐에 1번 노드만 삽입하게 된다.
[결과] 1 -> 2 -> 5 -> 3 -> 6 -> 4 -> 7
※ 위상 정렬의 답안은 여러 가지가 될 수 있다는 점이 특징이다.
따라서 1 -> 5 -> 2 -> 3 -> 6 -> 4 -> 7
도 하나의 답이 될 수 있다.
def topology_sort():
queue = deque()
# 진입차수가 0인 모든 노드를 큐에 넣음
for i in range(1,N+1):
if indegree[i] == 0:
queue.append(i)
while queue:
current = queue.popleft()
# 현재 노드와 연결된 모든 노드의 진입차수 감소
for next in graph[current]:
indegree[next] -= 1
if indegree[next] == 0:
queue.append(next)