簡體   English   中英

為什么我們需要霍夫曼樹代碼的unsigned char

[英]Why do we need unsigned char for Huffman tree code

我正在嘗試創建一個霍夫曼樹,我讀到的問題對我來說很奇怪,它如下:

鑒於以下數據結構:

 struct huffman { unsigned char sym; /* symbol */ struct huffman *left, *right; /* left and right subtrees */ }; 

編寫一個以二進制文件名作為唯一參數的程序,假設原子(基本符號)是8位無符號字符,構建該文件的霍夫曼樹,並打印樹和字典。
必須使用除malloc()之外的其他任何操作來完成分配,並且可以使用qsort()完成排序。

這讓我感到困惑的是,編寫一個程序來創建一個霍夫曼樹,我們只需要做以下事情:

  1. 我們需要一個頻率數組(可能是Farray[]={.......}
  2. 對它進行排序並添加兩個最小的節點以形成樹,直到它沒有離開1個最終節點(即頭部)。

現在的問題是:我們為什么以及在哪里需要那些未簽名的char數據? (這個問題想要什么類型的unsigned char數據,我認為只有頻率足以顯示一個Huffman樹)?

如果你純粹想要顯示樹的形狀 ,那么是的,你只需要構建它。 但是,對於任何用途,您需要知道每個節點代表什么原始符號。

想象一下你的輸入符號是[ABCD]。 想象中的霍夫曼樹/字典可能如下所示:

         ( )
        /   \              A = 1
      ( )   (A)            B = 00
     /   \                 C = 010
   (B)   ( )               D = 011
        /   \
      (C)   (D)

如果你不存儲sym ,它看起來像這樣:

         ( )
        /   \              A = ?
      ( )   ( )            B = ?
     /   \                 C = ?
   ( )   ( )               D = ?
        /   \
      ( )   ( )

不是很有用,那是嗎?

編輯2:計划中缺少的步驟是步驟0:從文件構建頻率數組(不知怎的,我錯過了你不需要實際編碼文件)。 這不是實際的霍夫曼算法本身的一部分,我找不到一個合適的例子來鏈接,所以這里有一個粗略的想法:

FILE *input = fopen("inputfile", "rb");
int freq[256] = {0};
int c;
while ((c = fgetc(input)) != EOF)
    freq[c]++;
fclose(input);

/* do Huffman algorithm  */
...

現在,仍然需要改進,因為它既不使用malloc()也不使用文件名作為參數,但它不是我的功課;)

我這樣做了一段時間,但我認為生成的“字典”需要數據進行編碼 ,而“樹”則用於對其進行解碼 當然,你總是可以從另一個構建一個。

在解碼時,您遍歷樹(左/右,根據連續的輸入位),當您點擊終端節點(空指針)時,節點中的'sym'是輸出值。

通常數據壓縮分為兩大步驟; 給定一個數據流:

  • 評估給定符號在流中出現的概率,換句話說,您可以評估符號在數據集中出現的頻率
  • 一旦你研究了出現並用符合概率的符號創建你的表,你需要根據它們的概率對符號進行編碼,為了實現這個魔法,你創建了一個字典,原來的符號往往只是用另一個符號代替了大小越小,特別是對於數據集中經常使用的符號,字典會跟蹤編碼和解碼階段的這種替換。 霍夫曼為您提供了一種自動化此過程的算法,並獲得了相當不錯的結果。

在實踐中它比這更復雜,因為樹涉及,但主要目的始終是構建字典。

這里有一個完整的教程

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM