哈夫曼樹及其編碼
1、定義
- 樹的帶權路徑長度(WPL)
將樹的每一個節點附加一個權值,樹中所有葉子節點的帶權路徑長度之和成為該樹的帶權路徑長度。其計算公式如下:
- 哈夫曼樹
帶權路徑長度WPL最小的二叉樹成為哈夫曼樹(或最優二叉樹)。
- 哈夫曼編碼
規定哈夫曼樹種左分支為0,右分支為1,則從根節點到每個葉子節點所經過的分支對應的0和1組成的序列便為該節點對應字元的編碼,這樣的編碼成為哈夫曼編碼。
詳細定義可檢視部落格:https://blog.csdn.net/l494926429/article/details/52494926
2、應用
哈夫曼樹主要用於哈夫曼編碼,可以起到壓縮作用。
3、實現
(1)哈夫曼樹的型別定義
typedef struct HTNode
{
char data;
double weight;
int parent, left, right;
}HTNode;
(2)哈夫曼樹的構造演算法
//returns the huffman tree
HTNode* CreateHTNode(char* src, double* weight, int n)
{
int h_n = 2 * n - 1;
//init the huffman tree
HTNode* h = new HTNode[h_n];
for (int i = 0; i < n; i++)
{
h[i].data = src[i];
h[i].weight = weight[i];
h[i].parent = h[i].left = h[i].right = -1;
}
for (int i = n; i < h_n; i++)
h[i].parent = -1;
//create the huffman tree
int min1_index, min2_index; //the index of the least two weight
for(int i = n ; i < h_n; i++)
{
min1_index = min2_index = -1;
for (int j = 0; j < i; j++)
{
if (h[j].parent == -1)
{
if (min1_index == -1 || h[j].weight < h[min1_index].weight)
{
min2_index = min1_index;
min1_index = j;
}
else if (min2_index == -1 || h[j].weight < h[min2_index].weight)
{
min2_index = j;
}
}
}
h[i].weight = h[min1_index].weight + h[min2_index].weight;
h[i].left = min1_index;
h[i].right = min2_index;
h[min1_index].parent = h[min2_index].parent = i;
}
return h;
}
(3)哈夫曼編碼
//returns the huffman code of the huffman tree
map<char, string>* CreateHCode(HTNode* h, int n)
{
map<char, string>* m = new map<char, string>;
for (int i = 0; i < n; i++)
{
string t = "";
int k = i;
while (h[k].parent != -1)
{
if (h[h[k].parent].left == k)
t += '0';
else
t += '1';
k = h[k].parent;
}
reverse(t.begin(), t.end());
(*m)[h[i].data] = t;
}
return m;
}
4、測試
假設用於通訊的電文僅由 8 個字母組成,字母在電文中出現的頻率分別為 0.07,0.19,0.02,0.06,0.32,0.03,0.21,0.10。試為這 8 個字母設計哈夫曼編碼。
#include <iostream>
#include <string>
#include <map>
using namespace std;
typedef struct HTNode
{
char data;
double weight;
int parent, left, right;
}HTNode;
//returns the huffman tree
HTNode* CreateHTNode(char* src, double* weight, int n)
{
int h_n = 2 * n - 1;
//init the huffman tree
HTNode* h = new HTNode[h_n];
for (int i = 0; i < n; i++)
{
h[i].data = src[i];
h[i].weight = weight[i];
h[i].parent = h[i].left = h[i].right = -1;
}
for (int i = n; i < h_n; i++)
h[i].parent = -1;
//create the huffman tree
int min1_index, min2_index; //the index of the least two weight
for(int i = n ; i < h_n; i++)
{
min1_index = min2_index = -1;
for (int j = 0; j < i; j++)
{
if (h[j].parent == -1)
{
if (min1_index == -1 || h[j].weight < h[min1_index].weight)
{
min2_index = min1_index;
min1_index = j;
}
else if (min2_index == -1 || h[j].weight < h[min2_index].weight)
{
min2_index = j;
}
}
}
h[i].weight = h[min1_index].weight + h[min2_index].weight;
h[i].left = min1_index;
h[i].right = min2_index;
h[min1_index].parent = h[min2_index].parent = i;
}
return h;
}
//returns the huffman code of the huffman tree
map<char, string>* CreateHCode(HTNode* h, int n)
{
map<char, string>* m = new map<char, string>;
for (int i = 0; i < n; i++)
{
string t = "";
int k = i;
while (h[k].parent != -1)
{
if (h[h[k].parent].left == k)
t += '0';
else
t += '1';
k = h[k].parent;
}
reverse(t.begin(), t.end());
(*m)[h[i].data] = t;
}
return m;
}
int main()
{
const char data[] = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h' };
const double weight[] = {0.07, 0.19, 0.02, 0.06, 0.32, 0.03, 0.21, 0.10};
const int n = 8;
HTNode* h = CreateHTNode(const_cast<char*>(data), const_cast<double*>(weight), n);
map<char, string>* m = CreateHCode(h, n);
for (map<char, string>::iterator iter = m->begin(); iter != m->end(); iter++)
{
cout << iter->first << " : " << iter->second << endl;
}
delete []h, m;
system("pause");
return 0;
}
相關文章
- 6.6 哈夫曼樹及其應用
- Java 樹結構實際應用 二(哈夫曼樹和哈夫曼編碼)Java
- 哈夫曼編碼
- 哈夫曼樹
- 哈夫曼樹及其應用(檔案壓縮)
- 【資料結構X.11】程式碼實現 哈夫曼樹的建立,建立,構造,實現哈夫曼編碼資料結構
- 資料結構與演算法——赫夫曼樹(哈夫曼樹)資料結構演算法
- 哈夫曼編碼 —— Lisp 與 Python 實現LispPython
- 哈夫曼樹學習筆記筆記
- Task A2 哈夫曼樹的應用
- 從哈夫曼編碼中我們學到了什麼?
- 最優二叉樹(哈夫曼樹)Java實現二叉樹Java
- 資料結構-哈夫曼樹(python實現)資料結構Python
- 重學資料結構之哈夫曼樹資料結構
- 資料結構與演算法:哈夫曼樹資料結構演算法
- 高階資料結構---赫(哈)夫曼樹及java程式碼實現資料結構Java
- 小任的第一篇部落格-哈夫曼樹
- 【資料結構】哈夫曼樹的建立與基礎應用資料結構
- 有趣的赫夫曼樹
- 一本正經的聊資料結構(6):最優二叉樹 —— 哈夫曼樹資料結構二叉樹
- 曼哈頓距離與切比雪夫距離
- 資料結構之哈弗曼樹資料結構
- C#資料結構-赫夫曼樹C#資料結構
- 曼哈頓距離與切比雪夫距離的互化
- 哈夫曼實現檔案壓縮解壓縮(c語言)C語言
- 一本正經的聊資料結構(7):哈弗曼編碼資料結構
- 關於資料壓縮、信源編碼、赫夫曼碼的一些研究,以及由此引出對決策樹模型的資訊理論本質的思考模型
- 自編碼器及其相關模型模型
- 編譯python(cpython)的原始碼及其用途編譯Python原始碼
- 24. 平衡二叉樹,及其程式碼實現二叉樹
- 字首樹及其Java實現Java
- 字典樹及其C++實現C++
- 線段樹差分及其應用
- 資料視覺化高階技巧——以哈伯曼癌症生存資料為例視覺化
- 影片與編解碼的技術邂逅,碰撞出的高畫質羅曼史
- zkw 線段樹-原理及其擴充套件套件
- 資料編輯方案及其工具
- 農夫漁夫