record logo record

위상 정렬(Topology Sort) 이란?

그래프의 흐름을 ‘조건’ 으로 해석할 수 있다. 알고리즘 수업을 이수하기 위해서는 이전에 선 이수 과목인 이산수학과 자료구조를 이수해야만 알고리즘을 수강할 수 있다는 말이다.

위의 예시를 그대로 노드에 숫자로 표기한 그래프이다.

위상 정렬(Topology Sort) 알고리즘의 특징

위상 정렬(Topology Sort)의 알고리즘 예시

위와 같이 처음에는 진입차수가 0인 1번 노드가 큐에 들어가 있다.

결과적으로 1 2 4 3 5 6 7 8 순서로 정렬됨을 알 수 있다.

Source Code

#include <iostream>
#include <vector>
#include <queue>
#define MAX 10
using namespace std;

int n, inDegree[MAX];// inDegree: 진입 차수 
vector<int> a[MAX]; // 각 정점의 노드의 정보를 담는다. 

void topologySort() {
	int result[MAX];
	queue<int> q;
	// 진입 차수가 0인 노드를 큐에 삽입한다.
	for(int i = 1; i <= n; i++){
		if(inDegree[i] == 0) q.push(i);
	} 
	// 위상 정렬이 완전히 수행되려면 정확히 N개의 노드를 방문한다.
	for(int i = 1; i <= n; i++){
		// n개를 방문하기 전에 큐가 빈다면 사이클이 발생한 것.
		if(q.empty()){
			printf("사이클 발생!!");
			return; 
		}
		int x = q.front();
		q.pop();
		result[i] = x;
		for(int i = 0; i < a[x].size(); i++){
			int y = a[x][i];
			// 새롭게 진입차수가 0이 된 정점을 큐에 삽입한다. 
			if(--inDegree[y] == 0){
				q.push(y); 
			}
		}
	}
	for(int i = 1; i <= n; i++) {
		printf("%d ", result[i]);
	}
}

int main(void) {
	n = 7;
	a[1].push_back(2);
	inDegree[2]++;
	a[1].push_back(5);
	inDegree[5]++;
	a[2].push_back(3);
	inDegree[3]++;
	a[3].push_back(4);
	inDegree[4]++;
	a[4].push_back(6);
	inDegree[6]++;
	a[5].push_back(6);
	inDegree[6]++;
	a[6].push_back(7);
	inDegree[7]++;
	
	topologySort();
	
	return 0;
}

위상 정렬(Topology Sort)의 시간복잡도

위상 정렬정점의 갯수 + 간선의 갯수 만큼 소요되므로 매우 빠른 알고리즘 중 하나이다.

따라서, 시간 복잡도는 O(V + E) 이다.

References