이 영역을 누르면 첫 페이지로 이동
Arc 블로그의 첫 페이지로 이동

Arc

페이지 맨 위로 올라가기

Arc

[Algorithm] 위상 정렬(Topological Sort)

  • 2023.03.07 12:38
  • Algorithm/Algorithm
글 작성자: SeoArc

위상 정렬(Topological Sort)?

위상 정렬은 순서가 정해져있는 작업을 차례로 수행해야 할 때 그 순서를 결정해주기 위해 사용하는 알고리즘으로, 비순환 방향 그래프(DAG)에서 정점을 선형으로 정렬하는 것이다.

 

실생활을 예로 들면,

인터넷 검색을 하기 위해선 다음과 같은 순서로 행동해야한다.

컴퓨터 전원 키기 -> 브라우저 키기 -> 검색 엔진 포털 진입 -> 검색

위 순서가 바뀐다면 검색을 할 수 없을 것이다.

 

위상 정렬은 모든 간선 (u, v)에 대해 정점 u가 정점 v보다 먼저 오는 순서로 정렬이 된다.

그래프가 DAG가 아닌 경우 그래프에 대한 위상 정렬은 불가능하다.

 

BFS 예시 코드 수행 시
DFS 예시 코드 수행 시

여기서 주의할 점은 E가 수행되기 위해선 B와 D가 모두 수행되어야 한다는 점이다.

 

비순환 방향 그래프 (DAG: Directed Acyclic Graph)?

비순환 방향 그래프(DAG)는 사이클이 없는 방향 그래프이다.

DAG는 이벤트 간의 우선순위를 나타내기 위해 주로 사용된다.

 

 

구현

위상 정렬은 BFS, DFS 두 가지 방식으로 구현할 수 있다.

 

BFS로 구현

  1. 모든 정점의 진입 차수(inDegree)를 설정한다.
  2. 진입차수가 0인 정점을 방문한 것으로 표시하고 해당 정점을 Queue에 추가한다.
  3. Queue에서 요소를 꺼내 인접한 정점 중 방문하지 않은 정점들의 진입차수를 하나씩 감소시킨다.
  4. 진입차수가 0이된 정점은 Queue에 추가한다.
  5. Queue가 비어있을 때까지 순회하며 2 ~ 4 과정을 반복한다.
import java.util.*;

public class TopologicalSortByBFS {

    private static int[][] graph = {{},
            {2, 4},
            {3, 5},
            {},
            {5},
            {6},
            {}};
    private static int[] inDegree;
    public static void main(String[] args) {
        inDegree = new int[graph.length];

        setInDegree();
        search();
    }

    public static void setInDegree() {
        for (int i = 1; i < graph.length; i++) {
            for (int next : graph[i]) {
                inDegree[next]++;
            }
        }
    }

    public static void search() {
        Deque<Integer> dq = new ArrayDeque<>();
        for (int i = 1; i < graph.length; i++) {
            if (inDegree[i] == 0) {
                dq.offerLast(i);
            }
        }

        for (int i = 1; i < graph.length; i++) {
            if (dq.isEmpty()) {
                return;
            }
            
            int cur = dq.poll();
            System.out.print(cur + " ");

            for (int next : graph[cur]) {
                if (--inDegree[next] == 0) {
                    dq.offer(next);
                }
            }
        }
    }
}

 

DFS로 구현

  1. 임의의 정점에서 다음과 같이 DFS를 수행한다.
  2. 방문 표시를 하면서 간선을 따라 다음 정점으로 방문한다.
  3. 더 이상 방문할 간선이 없으면 정점을 Queue 또는 Stack 첫번째에 추가한다.
  4. 모든 정점을 탐색할 때 까지 2 ~ 3을 반복 수행한다.
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Deque;
import java.util.List;

public class TopologicalSortByDFS {

    private static int[][] graph = {{},
            {2, 4},
            {3, 5},
            {},
            {5},
            {6},
            {}};
    private static Deque<Integer> vertexes;
    private static boolean[] visited;
    public static void main(String[] args) {
        vertexes = new ArrayDeque<>();
        visited = new boolean[graph.length];

        for (int i = 1; i < graph.length; i++) {
            if (visited[i]) {
                continue;
            }
            search(i);
        }

        System.out.println(vertexes);
    }

    public static void search(int cur) {
    	visited[cur] = true;
        for (int next : graph[cur]) {
            if (visited[next]) {
                continue;
            }
            search(next);
        }

        vertexes.addFirst(cur);
    }
}

 

'Algorithm > Algorithm' 카테고리의 다른 글

[Algorithm] 이진 탐색(Binary Search)  (0) 2023.03.11
[Algorithm] 모듈러 산술(modular Arithmetic)  (0) 2023.03.09
[Algorithm] 프림 알고리즘(Prim's algorithm)  (0) 2023.02.28
[Algorithm] 다익스트라(Dijkstra)  (0) 2023.02.26
[Algorithm] 크루스칼 알고리즘 (Kruskal Algorithm)  (0) 2023.02.19

댓글

이 글 공유하기

  • 구독하기

    구독하기

  • 카카오톡

    카카오톡

  • 라인

    라인

  • 트위터

    트위터

  • Facebook

    Facebook

  • 카카오스토리

    카카오스토리

  • 밴드

    밴드

  • 네이버 블로그

    네이버 블로그

  • Pocket

    Pocket

  • Evernote

    Evernote

다른 글

  • [Algorithm] 이진 탐색(Binary Search)

    [Algorithm] 이진 탐색(Binary Search)

    2023.03.11
  • [Algorithm] 모듈러 산술(modular Arithmetic)

    [Algorithm] 모듈러 산술(modular Arithmetic)

    2023.03.09
  • [Algorithm] 프림 알고리즘(Prim's algorithm)

    [Algorithm] 프림 알고리즘(Prim's algorithm)

    2023.02.28
  • [Algorithm] 다익스트라(Dijkstra)

    [Algorithm] 다익스트라(Dijkstra)

    2023.02.26
다른 글 더 둘러보기

정보

Arc 블로그의 첫 페이지로 이동

Arc

  • Arc의 첫 페이지로 이동

검색

메뉴

  • 홈
  • 태그
  • 방명록

카테고리

  • 분류 전체보기 (106)
    • Language (28)
      • C++ (0)
      • C# (0)
      • Java (28)
    • Algorithm (47)
      • Algorithm (15)
      • Data Structure (6)
      • PS (26)
    • Computer Science (22)
      • Design Pattern (1)
      • Network (14)
      • OS (7)
    • Game (0)
      • Unity (0)
    • Backend (3)
      • Spring (1)
      • JPA (2)
    • DB (0)
      • SQL (0)
    • DevOps (2)
      • AWS (0)
      • Docker (2)
      • Jenkins (0)
      • Nginx (0)
    • Software Engineering (4)
      • OOP (4)
    • AI (0)
      • Machine Learning (0)
    • Others (0)

최근 글

인기 글

댓글

공지사항

아카이브

태그

  • 자바
  • algorithm
  • java
  • network
  • graph
  • 알고리즘
  • 그래프
  • 네트워크

나의 외부 링크

정보

SeoArc의 Arc

Arc

SeoArc

블로그 구독하기

  • 구독하기
  • RSS 피드

방문자

  • 전체 방문자
  • 오늘
  • 어제

티스토리

  • 티스토리 홈
  • 이 블로그 관리하기
  • 글쓰기
Powered by Tistory / Kakao. © SeoArc. Designed by Fraccino.

티스토리툴바