카테고리 없음 2021. 5. 3. 22:57

허프만 압축(Huffman Coding)

  • 문자를 0과 1로 표현하여 압축하는 방법이다.

  • 접두부 특성(Prefix Property)가 존재한다.

    • 압축된 이진 코드가 다른 이진 코드의 접두부가 되지 않는 특성을 의미한다.

    • https://ko.wikipedia.org/wiki/%EC%95%9E%EC%9E%90%EB%A6%AC_%EB%B6%80%ED%98%B8

    • 예를 들면, 변환된 이진 코드가 {1, 10} 두 가지라면 "1"은 "10"의 앞부분에 포함되므로 이는 접두부 특성이 없는 것이다.

    • 반면에 {0, 10} 의 경우 "0"과 "10"은 반드시 구분되므로 접두부 특성을 가진다.


알고리즘

  • 각 문자의 출현 빈도수에 따라 이진 코드를 할당한다.

    • 빈도수가 많을수록 짧은 이진 코드를 할당하는게 효율적이다.

    • 이진 트리와 우선순위 큐를 사용한다.

      Pseudo Code

      HuffmanTree HuffmanCoding(문자 각각에 대한 빈도수)
      {
        각 문자에 대해 빈도수를 저장하는 노드를 생성한다.
        빈도수에 대한 우선순위 큐를 만들고 모든 노드를 큐에 넣는다.
        while (큐에 노드가 2개 이상일 경우)
        {
          빈도수가 가장 작은 2개의 노드를 큐에서 pop한다.
          새 노드를 만들어 위에서 pop한 2개의 노드를 자식 노드로 만든다.
          새 노드의 빈도수는 각 노드의 빈도수의 합이다.
          새 노드를 우선순위 큐에 삽입한다.
        }
        return (Q에 남은 노드);
      }

예제

  • 문자 A, G, C, T에 대한 빈도수가 각각 450, 120, 270, 90일 경우 다음과 같은 순서를 따른다.

  • 결과적으로 A, G, C, T는 각각 허프만 코드로 0, 100, 11, 101이 된다.

  • 이진 트리의 특성에 따라 빈도수가 높을 수록 루트 노드와 가까우므로 짧은 코드에 대응되고, 접두부 특성을 지님을 알 수 있다.

  • 압축비

    • 허프만 코드로 변환하기 전 문자들의 용량은 (450 + 120 + 270 + 90) * 1byte * 8bit/1byte = 7440bit이다.

    • 변환 후의 용량은 (450 * 1) + (120 * 3) + (270 * 2) + (90 * 3) = 1620bit이다.

    • 따라서 압축비 = (압축 전 크기) / (압축 후 크기) = 7440 / 1620 = 4.593 이다.

      • 약 1/4.6의 크기로 압축된 것을 알 수 있다.

시간 복잡도

  • 각 빈도수를 노드에 저장할 때 O(n) 시간이 걸린다.

  • 우선순위 큐로 힙 자료구조를 사용하면 O(n) 시간이 걸린다.

  • 루프는 (n - 1)번 반복된다.

    • 큐에서 최소 빈도수 노드 2개를 삭제 후 새 노드를 큐에 다시 삽입하는 과정에서 O(logn)이 걸린다.

    • 즉 루프의 시간 복잡도는 O(nlogn)이다.

  • 따라서 허프만 코딩의 시간 복잡도는 O(nlogn)이다.