[Java] μœ„μƒ μ •λ ¬(Topological Sort) κ°œλ…κ³Ό κ΅¬ν˜„

2025. 11. 14. 12:49Β·β˜•Java

μœ„μƒ μ •λ ¬μ΄λž€

κ·Έλž˜ν”„ μ •λ ¬ μ•Œκ³ λ¦¬μ¦˜μ˜ μΌμ’…μœΌλ‘œ, μˆœμ„œκ°€ μ •ν•΄μ Έ μžˆλŠ” 일련의 μž‘μ—…μ„ μ°¨λ‘€λŒ€λ‘œ μˆ˜ν–‰ν•΄μ•Ό ν•  λ•Œ μ‚¬μš©ν•˜λŠ” μ•Œκ³ λ¦¬μ¦˜μž…λ‹ˆλ‹€.

 

μœ„μƒ 정렬이 κ°€λŠ₯ν•˜λ €λ©΄ DAG(Directed Acyclic Graph)이어야 ν•©λ‹ˆλ‹€.

  1. λ°©ν–₯μ„± O: Node A → Node B와 같이 두 λ…Έλ“œ 사이 λ°©ν–₯이 μžˆμ–΄μ•Ό ν•©λ‹ˆλ‹€.
  2. 사이클 X: A → B, B → Aμ•„ 같은 사이클이 μ—†μ–΄μ•Ό ν•©λ‹ˆλ‹€.

 

예λ₯Ό λ“€μ–΄, 총 3개의 κ³Όλͺ©μ΄ 있고, ν•œ κ³Όλͺ©μ„ λ“£κΈ° μœ„ν•œ μ„ μ΄μˆ˜κ³Όλͺ© 관계가 ν‘œμ‹œλ˜μ–΄ μžˆμŠ΅λ‹ˆλ‹€.

μ„Έ κ³Όλͺ©μ„ λͺ¨λ‘ λ“£λŠ” μ½”μŠ€λŠ” `ν”„λ‘œκ·Έλž˜λ° 기초  → C ν”„λ‘œκ·Έλž˜λ°  → κ³ κΈ‰ C ν”„λ‘œκ·Έλž˜λ°`의 μˆœμ„œκ°€ λ˜μ–΄μ•Ό ν•©λ‹ˆλ‹€.

`κ³ κΈ‰ C ν”„λ‘œκ·Έλž˜λ°  → C ν”„λ‘œκ·Έλž˜λ°  → ν”„λ‘œκ·Έλž˜λ° 기초` μˆœμ„œλŠ” μ•ˆ λ˜λŠ” κ²λ‹ˆλ‹€.

이처럼 κ·Έλž˜ν”„μ—μ„œ λ°©ν–₯성을 톡해 μ μ ˆν•œ μˆœμ„œλ₯Ό μ°ΎλŠ” 것이 μœ„μƒ μ •λ ¬μž…λ‹ˆλ‹€.


μ•Œκ³ λ¦¬μ¦˜ κ΅¬ν˜„

κ΅¬ν˜„ μ „ μ•Œμ•„μ•Όν•˜λŠ” μš©μ–΄κ°€ μžˆμŠ΅λ‹ˆλ‹€.

  • μ§„μž… 차수(Indegree)
    • νŠΉμ •ν•œ λ…Έλ“œλ‘œ λ“€μ–΄μ˜€λŠ” κ°„μ„ μ˜ 개수
    • μ•„λž˜ κ·Έλž˜ν”„μ—μ„œ 6의 μ§„μž… μ°¨μˆ˜λŠ” 2
  • μ§„μΆœ 차수(Outdegree)
    • νŠΉμ •ν•œ λ…Έλ“œμ—μ„œ λ‚˜κ°€λŠ” κ°„μ„ μ˜ 개수
    • μ•„λž˜ κ·Έλž˜ν”„μ—μ„œ 5의 μ§„μΆœ μ°¨μˆ˜λŠ” 1

 

μœ„μƒ 정렬은 큐λ₯Ό μ΄μš©ν•˜μ—¬ λ‹€μŒκ³Ό 같은 λ‹¨κ³„λ‘œ κ΅¬ν˜„ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

νμ—μ„œ κΊΌλ‚΄μ§€λŠ” μˆœμ„œκ°€ μœ„μƒ μ •λ ¬ κ²°κ³Όμž…λ‹ˆλ‹€.

 

πŸ’― μœ„μƒ μ •λ ¬ κ΅¬ν˜„ 곡식

1. μ§„μž…μ°¨μˆ˜κ°€ 0인 λ…Έλ“œλ₯Ό 큐에 λ„£λŠ”λ‹€.
2. 큐가 빌 λ•ŒκΉŒμ§€ λ‹€μŒμ˜ 과정을 λ°˜λ³΅ν•œλ‹€.
    1. νμ—μ„œ μ›μ†Œλ₯Ό κΊΌλ‚΄ ν•΄λ‹Ή λ…Έλ“œμ—μ„œ λ‚˜κ°€λŠ” 간선을 κ·Έλž˜ν”„μ—μ„œ μ œκ±°ν•œλ‹€.
    2. μƒˆλ‘­κ²Œ μ§„μž…μ°¨μˆ˜κ°€ 0이 된 λ…Έλ“œλ₯Ό 큐에 μ‚½μž…ν•œλ‹€.

 

1단계에 따라,

μ§„μž…μ°¨μˆ˜κ°€ 0인 λ…Έλ“œλ₯Ό 큐에 λ„£μœΌλ©΄ λ…Έλ“œ 1이 처음으둜 λ“€μ–΄κ°‘λ‹ˆλ‹€.

2-1단계에 따라 큐에 μžˆλŠ” λ…Έλ“œ 1을 κΊΌλ‚΄κ³ (=1이 좜λ ₯λ©λ‹ˆλ‹€) λ…Έλ“œ 1을 μ‚­μ œν•©λ‹ˆλ‹€.

이둜써 μƒˆλ‘­κ²Œ μ§„μž… μ°¨μˆ˜κ°€ 0이 된 λ…Έλ“œ 2와 λ…Έλ“œ 5κ°€ 큐에 λ“€μ–΄κ°‘λ‹ˆλ‹€.

 

λ…Έλ“œ 2와 λ…Έλ“œ 5κ°€ 큐에 λ“€μ–΄κ°€λŠ” μˆœμ„œλŠ” μš”κ΅¬μ‚¬ν•­μ— 따라 λ‹¬λ¦¬μ§ˆ 수 μžˆμŠ΅λ‹ˆλ‹€. κ·Έλƒ₯ μ˜€λ¦„μ°¨μˆœμœΌλ‘œ λ„£μ—ˆμŠ΅λ‹ˆλ‹€.

 

λ…Έλ“œ 2와 λ…Έλ“œ 5까 νμ—μ„œ κΊΌλ‚΄μ§€κ³  κ·Έλž˜ν”„μ—μ„œ μ‚­μ œλ˜λ©΄μ„œ

λ…Έλ“œ 3κ³Ό λ…Έλ“œ 6의 μ§„μž… μ°¨μˆ˜κ°€ 0이 λ©λ‹ˆλ‹€.

 

μ΄μ–΄μ§€λŠ” 과정은 그림으둜 μ‚΄νŽ΄λ³΄κ² μŠ΅λ‹ˆλ‹€.

 

 

 

큐가 λΉ„κ³ , λͺ¨λ“  λ…Έλ“œκ°€ μ‚­μ œλ˜λ©΄μ„œ 정렬이 λλ‚¬μŠ΅λ‹ˆλ‹€.

μ •λ ¬ κ²°κ³ΌλŠ” `1→2 →5 →3 →6 →4 →7`μž…λ‹ˆλ‹€.

 


Java둜 κ΅¬ν˜„

import java.util.*;

public class TopologicalSort {

  public static void main(String[] args) {
    int n = 7;  // λ…Έλ“œ 개수
    
    // 인접 리슀트 생성
    List<List<Integer>> adj = new ArrayList<>();
    for (int i = 0; i <= n; i++) {
      adj.add(new ArrayList<>());
    }
    addEdge(adj, 1, 2); // 1->2
    addEdge(adj, 1, 5);
    addEdge(adj, 2, 3);
    addEdge(adj, 2, 6);
    addEdge(adj, 3, 4);
    addEdge(adj, 4, 7);
    addEdge(adj, 5, 6);

    topologicalSort(n, adj);
  }

  public static void topologicalSort(int n, List<List<Integer>> adj) {
    Queue<Integer> queue = new LinkedList<>();

    // step1: μ§„μž…μ°¨μˆ˜κ°€ 0인 λ…Έλ“œ 큐에 λ„£κΈ°
    // μ§„μž…μ°¨μˆ˜ 계산
    int[] indegree = new int[n+1];  // 0번 λ…Έλ“œλŠ” μƒλž΅ν•˜λ―€λ‘œ n+1 크기둜
    for(int i=1; i<=n; i++) {
      for(int next : adj.get(i)) indegree[next]++;
    }
    // 큐에 λ„£κΈ°
    for(int i=1; i<=n; i++) {
      if(indegree[i]==0) queue.add(i);
    }

    // step2
    while(!queue.isEmpty()) {
      // νμ—μ„œ κΊΌλ‚΄κΈ°
      int peek = queue.poll();
      System.out.print(peek + " ");
      // ν•΄λ‹Ή λ…Έλ“œμ—μ„œ λ‚˜κ°€λŠ” κ°„μ„  제거
      for(int next : adj.get(peek)) {
        indegree[next]--; // μ§„μž…μ°¨μˆ˜ -1
        if(indegree[next]==0)
          // μƒˆλ‘­κ²Œ μ§„μž…μ°¨μˆ˜κ°€ 0이 된 λ…Έλ“œ 큐에 μΆ”κ°€
          queue.add(next);
      }
    }
  }

  public static void addEdge(List<List<Integer>> adj, int from, int to) {
    adj.get(from).add(to);
  }
}

 

좜λ ₯ κ²°κ³Ό: 1 2 5 3 6 4 7 

'β˜•Java' μΉ΄ν…Œκ³ λ¦¬μ˜ λ‹€λ₯Έ κΈ€

[Java] μš°μ„ μˆœμœ„ 큐(Priority Queue) κ°œλ…κ³Ό μžλ°” κΈ°λ³Έ λ©”μ†Œλ“œ  (0) 2025.11.13
[Java] κ°€λΉ„μ§€ μ»¬λ ‰μ…˜(Garbage Collection) κΈ°λ³Έ κ°œλ…  (0) 2025.10.18
[Java] JVMμ΄λž€? κ°œλ…κ³Ό μžλ°” 컴파일 κ³Όμ • μ΄ν•΄ν•˜κΈ°  (0) 2025.10.03
[Java] λ©€ν‹°μŠ€λ ˆλ“œ ν™˜κ²½μ—μ„œμ˜ 경쟁 μƒνƒœμ™€ ν•΄κ²° μ „λž΅ 정리  (1) 2025.06.02
[자료ꡬ쑰][Java] HashSet 쀑볡 제거 λ™μž‘ 원리: HashSet은 μ–΄λ–»κ²Œ 쀑볡을 ν™•μΈν•˜λ‚˜μš”?  (0) 2025.02.13
'β˜•Java' μΉ΄ν…Œκ³ λ¦¬μ˜ λ‹€λ₯Έ κΈ€
  • [Java] μš°μ„ μˆœμœ„ 큐(Priority Queue) κ°œλ…κ³Ό μžλ°” κΈ°λ³Έ λ©”μ†Œλ“œ
  • [Java] κ°€λΉ„μ§€ μ»¬λ ‰μ…˜(Garbage Collection) κΈ°λ³Έ κ°œλ…
  • [Java] JVMμ΄λž€? κ°œλ…κ³Ό μžλ°” 컴파일 κ³Όμ • μ΄ν•΄ν•˜κΈ°
  • [Java] λ©€ν‹°μŠ€λ ˆλ“œ ν™˜κ²½μ—μ„œμ˜ 경쟁 μƒνƒœμ™€ ν•΄κ²° μ „λž΅ 정리
μ†Œμ˜ πŸ€
μ†Œμ˜ πŸ€
Hello World ✨
  • μ†Œμ˜ πŸ€
    Soyoung's Dev Lab
    μ†Œμ˜ πŸ€
  • 전체
    였늘
    μ–΄μ œ
  • κΈ€μ“°κΈ° 관리
    • λΆ„λ₯˜ 전체보기 (79)
      • πŸ“’ κ²Œμ‹œνŒ (0)
      • 🌿Spring (20)
      • β˜•Java (7)
        • μ½”λ”©ν…ŒμŠ€νŠΈ (7)
      • βš™οΈ CS (26)
        • πŸ›œ λ„€νŠΈμ›Œν¬ (5)
        • πŸ“Š λ°μ΄ν„°λ² μ΄μŠ€ (8)
        • πŸ–²οΈμš΄μ˜μ²΄μ œ (9)
        • πŸ“š 자료ꡬ쑰 & μ•Œκ³ λ¦¬μ¦˜ (4)
      • πŸ“€ 배포 (4)
        • Docker (4)
        • AWS (0)
      • πŸ“° 기타 개발 자료 (12)
      • πŸ–₯️ ν”„λ‘œμ νŠΈ (0)
      • πŸ‘©‍πŸ’» ν™œλ™ & ν›„κΈ° (1)
      • 🍡 이야기 (2)
  • λΈ”λ‘œκ·Έ 메뉴

    • νƒœκ·Έ
  • 링크

    • github
    • velog
  • 곡지사항

  • 인기 κΈ€

  • νƒœκ·Έ

    객체지ν–₯ν”„λ‘œκ·Έλž˜λ°
    λ°μ΄ν„°λ² μ΄μŠ€
    Spring
    자료ꡬ쑰
    개발
    μ½”λ“œμž‡ μŠ€ν”„λ¦°νŠΈ
    Spring Security
    μœ„ν΄λ¦¬ 페이퍼
    운영체제
    docker
    μ•Œκ³ λ¦¬μ¦˜
    μ„œλ²„
    GIT
    기술 λ©΄μ ‘
    μ½”λ”©ν…ŒμŠ€νŠΈ
    λ„€νŠΈμ›Œν¬
    배포
    Java
  • 졜근 λŒ“κΈ€

  • hELLOΒ· Designed Byμ •μƒμš°.v4.10.3
μ†Œμ˜ πŸ€
[Java] μœ„μƒ μ •λ ¬(Topological Sort) κ°œλ…κ³Ό κ΅¬ν˜„
μƒλ‹¨μœΌλ‘œ

ν‹°μŠ€ν† λ¦¬νˆ΄λ°”