💡위상정렬이란?
위상정렬은 방향이 존재하는 그래프에서 정점들의 진행 순서를 지키며 모든 정점을 순서대로 나열하는 알고리즘이다.
간단한 예시로,
대학교 수업 과정을 생각해 보자.
- 자료구조 수업을 들으러면 먼저 프로그래밍 기초를 들어야 한다.
- 알고리즘 수업을 들으려면 먼저 자료구조를 들어야 한다.
- 운영체제 수업을 들으려면 먼저 자료구조를 들어야 한다.
이런 선수과목 관계를 위상정렬하게 되면 다음과 같은 순서가 나올 수 있다.
👨🏻💻 프로그래밍 기초 -> 자료구조 -> 알고리즘 -> 운영체제
❗️위상정렬의 주요 특징
- 순환(싸이클)이 없는 유향 그래프에서만 가능하다.
- 같은 그래프여도 여러 가지 위상 정렬이 나올 수 있다.
- 주로 스케쥴링이나 작업 순서 결정, 선수 과목 계산 등에 활용한다.
위상정렬 구현해 보기
1. 그래프에서 각 노드들의 진입차수를 설정한다.
진입 차수(Indegree)란, 방향 그래프의 한 정점에 대해 그 정점으로 들어오는 간선의 개수를 의미한다.
- 1번 노드의 진입차수: 0
- 2번 노드의 진입차수: 1
- 3번 노드의 진입차수: 1
- 4번 노드의 진입차수: 2
- 5번 노드의 진입차수: 1
- 6번 노드의 진입차수: 2
- 7번 노드의 진입차수: 1
int[] inDegree = {0, 0, 1, 1, 2, 1, 2, 1};
// 0번 인덱스부터 시작한다. 0번 인덱스는 사용하지 않는다.
// 1번 인덱스는 1번 노드, 2번 인덱스는 2번 노드 ...
2. 진입차수가 0인 정점들을 큐에 삽입한다.
Queue<Integer> q = new LinkedList<>();
for (int i = 1; i < inDegree.length; i++) {
if (inDegree[i] == 0) {
q.offer(i);
}
}
3. 인접한 정점들의 진입차수를 감소하며 순서를 정한다. 진입차수가 0이 되면 큐에 삽입한다.
System.out.println("===위상정렬 결과===");
while (!q.isEmpty()) {
int cur = q.poll();
System.out.print(cur + " ");
for (int node : adjList.get(cur)) {
inDegree[node]--;
if (inDegree[node] == 0) {
q.offer(node);
}
}
}
System.out.println();
위 과정을 시각화하여 살펴보자.
1. 진입 차수가 0인 모든 노드를 큐에 넣는다.
2. 큐에서 노드 1을 꺼낸 뒤 1에서 뻗어나가는 간선을 제거한다 -> 1에서 출발하여 도달하는 노드의 진입차수가 -1 줄어든다.
- 진입차수가 0이 된 노드들을 큐에 삽입한다.
3. 큐에서 노드 2를 꺼낸 뒤 2에서 뻗어나가는 간선을 제거한다. 2에서 출발하여 도달하는 노드의 진입차수가 -1 줄어든다.
- 진입차수가 0이 된 노드들을 큐에 삽입한다.
4. 큐에서 노드 5를 꺼낸 뒤 5에서 뻗어나가는 간선을 제거한다. 5에서 출발하여 도달하는 노드의 진입차수가 -1 줄어든다.
- 진입차수가 0이 된 노드들을 큐에 삽입한다.
5. 큐에서 노드 3을 꺼낸 뒤 3에서 뻗어나가는 간선을 제거한다. 3에서 출발하여 도달하는 노드의 진입차수가 -1 줄어든다.
- 진입차수가 0이 된 노드들을 큐에 삽입한다.
6. 큐에서 노드 6을 꺼낸 뒤 6에서 뻗어나가는 간선을 제거한다. 6에서 출발하여 도달하는 노드의 진입차수가 -1 줄어든다.
- 진입차수가 0이 된 노드들을 큐에 삽입한다.
7. 큐에서 노드 4를 꺼낸 뒤 4에서 뻗어나가는 간선을 제거한다. 4에서 출발하여 도달하는 노드의 진입차수가 -1 줄어든다.
- 진입차수가 0이 된 노드들을 큐에 삽입한다.
8. 큐에서 노드 7을 꺼낸 뒤 7에서 뻗어나가는 간선을 제거한다. 7에서 출발하여 도달하는 노드의 진입차수가 -1 줄어든다.
- 진입차수가 0 이 된 노드들을 큐에 삽입한다.
위상 정렬 결과
1 2 5 3 6 4 7
reference: https://freedeveloper.tistory.com/390
'Algorithm' 카테고리의 다른 글
[백준] 2156 포도주 시식 -JAVA (0) | 2025.01.27 |
---|---|
[백준] 2512 예산 - JAVA (0) | 2025.01.19 |
[TIP💡] 인텔리제이(Intellij)로 코딩테스트 환경 구성하기 (입출력을 txt로?) (0) | 2024.10.02 |
[백준] 13418 학교 탐방하기 - JAVA (0) | 2024.09.22 |
[SWEA] 2477 차량 정비소 - JAVA (0) | 2024.09.06 |