문제 12 · 허프만 코드
문제 12 [4점]
어떤 파일이 총 7개의 문자(a: 6개, b: 13개, c: 31개, d: 2개, e: 1개, f: 5개, g: 12개)를 가지고 있다고 할 때, 이를 압축하고자 한다. 압축 알고리즘 중 하나인 허프만 알고리즘Huffman's algorithm을 서술(2점)하고, 이를 이용하여 구현된 허프만 코드Huffman code를 그리시오(2점).
풀이 및 해설
허프만 알고리즘
자주 나오는 문자에 짧은 코드, 드문 문자에 긴 코드를 주는 접두어 코드prefix code를 만든다. 탐욕적으로 다음을 반복한다.
- 각 문자를 빈도를 가중치로 하는 리프 노드로 만들어 최소 우선순위 큐에 넣는다.
- 큐에서 가중치가 가장 작은 두 노드를 꺼내, 이 둘을 자식으로 하고 가중치를 두 값의 합으로 하는 새 내부 노드를 만든다.
- 새 노드를 큐에 넣는다. 노드가 하나 남을 때까지 반복한다. 남은 노드가 트리의 루트다.
- 루트에서 왼쪽 간선을
0, 오른쪽 간선을1로 두고, 각 리프까지의 경로가 그 문자의 코드가 된다.
병합 과정 (빈도: e1, d2, f5, a6, g12, b13, c31, 합 70)
| 단계 | 꺼낸 두 노드 | 합친 가중치 |
|---|---|---|
| 1 | e(1), d(2) | 3 |
| 2 | (ed)3, f(5) | 8 |
| 3 | a(6), (edf)8 | 14 |
| 4 | g(12), b(13) | 25 |
| 5 | (aedf)14, (gb)25 | 39 |
| 6 | c(31), 39 | 70 |
허프만 트리와 코드 (왼쪽=0, 오른쪽=1)
text
(70)
0/ \1
c (39)
0/ \1
(14) (25)
0/ \1 0/ \1
a (8) g b
0/ \1
(3) f
0/ \1
e d| 문자 | 빈도 | 코드 | 길이 |
|---|---|---|---|
| c | 31 | 0 | 1 |
| a | 6 | 100 | 3 |
| f | 5 | 1011 | 4 |
| e | 1 | 10100 | 5 |
| d | 2 | 10101 | 5 |
| g | 12 | 110 | 3 |
| b | 13 | 111 | 3 |
압축 후 총 비트 수(가중 경로 길이)는 내부 노드 가중치의 합과 같다.
(같은 가중치를 꺼내는 순서에 따라 코드 모양은 달라질 수 있으나, 총 비트 수 159는 최적으로 항상 동일하다. 고정 길이 3비트라면