[알고리즘] Topological Sort - 위상 정렬

2024. 11. 10. 15:51·Algorithm

💡위상정렬이란?

위상정렬은 방향이 존재하는 그래프에서 정점들의 진행 순서를 지키며 모든 정점을 순서대로 나열하는 알고리즘이다.

 

간단한 예시로,

 

대학교 수업 과정을 생각해 보자.

  • 자료구조 수업을 들으러면 먼저 프로그래밍 기초를 들어야 한다.
  • 알고리즘 수업을 들으려면 먼저 자료구조를 들어야 한다.
  • 운영체제 수업을 들으려면 먼저 자료구조를 들어야 한다.

 

이런 선수과목 관계를 위상정렬하게 되면 다음과 같은 순서가 나올 수 있다.

👨🏻‍💻 프로그래밍 기초 -> 자료구조 -> 알고리즘 -> 운영체제

 

❗️위상정렬의 주요 특징

  1. 순환(싸이클)이 없는 유향 그래프에서만 가능하다.
  2. 같은 그래프여도 여러 가지 위상 정렬이 나올 수 있다.
  3. 주로 스케쥴링이나 작업 순서 결정, 선수 과목 계산 등에 활용한다.

 

 

 

위상정렬 구현해 보기

 

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
'Algorithm' 카테고리의 다른 글
  • [백준] 2156 포도주 시식 -JAVA
  • [백준] 2512 예산 - JAVA
  • [TIP💡] 인텔리제이(Intellij)로 코딩테스트 환경 구성하기 (입출력을 txt로?)
  • [백준] 13418 학교 탐방하기 - JAVA
의중
의중
  • 의중
    개발어려워
    의중
  • 전체
    오늘
    어제
    • 전체글 (29)
      • Algorithm (12)
      • SSAFY (1)
      • 자료구조 (4)
      • 운영체제 (2)
      • JAVA (2)
      • ML, DL (0)
      • BackEnd (4)
      • DevOps (1)
      • 네트워크 (3)
  • hELLO· Designed By정상우.v4.10.3
의중
[알고리즘] Topological Sort - 위상 정렬
상단으로

티스토리툴바