哈夫曼树
哈夫曼编码
- 建立哈夫曼树
- 对应哈夫曼编码
- 由编码对应原数据
- 带权路径长度
#include<iostream>
#include<stack>
using namespace std;
typedef struct
{
int weght;
int left;
int right;
int parent;
}HuffNode,*HuffTree;
void Select(HuffTree& hf, int len, int& m1, int& m2);
void CreateHuffManTree(HuffTree& hf, int arr[], int len);
void PreOrder_Huffman(HuffTree hf, int len);
void HuffManDeCode(HuffTree hf, char code[], int len, int n);
char** HuffManCode(HuffTree hf, int len);
int WPLHuffManTree(HuffTree hf, int len);
void CreateHuffManTree(HuffTree& hf, int arr[], int len)
{
hf = new HuffNode[2 * len];
hf[0] = { 0,0,0,0 };
for (int i = 1; i <= len; i++)
{
hf[i] = { arr[i - 1],0,0,0 };
}
for (int i = len + 1; i <= 2 * len - 1; i++)
{
int m1, m2;
m1 = m2 = 0;
Select(hf, i - 1, m1, m2);
hf[i].left = m1, hf[i].right = m2;
hf[i].weght = hf[m1].weght + hf[m2].weght;
hf[i].parent = 0;
hf[m1].parent = hf[m2].parent = i;
}
}
void Select(HuffTree& hf, int len,int &m1,int&m2)
{
int min1, min2;
min1 = min2 = hf[1].weght;
for (int i = 1; i <= len; i++)
{
if (min1 > hf[i].weght && hf[i].parent == 0)
{
m1 = i;
min1 = hf[i].weght;
}
}
for (int i = 1; i <= len; i++)
{
if (min2 > hf[i].weght && i!=m1 && hf[i].parent == 0)
{
m2 = i;
min2 = hf[i].weght;
}
}
}
void PreOrder_Huffman(HuffTree hf, int len)
{
stack<HuffNode> s;
s.push(hf[len-1]);
while (!s.empty())
{
HuffNode h = s.top();
s.pop();
cout << h.weght << " " << h.parent << " " << h.left << " " << h.right << endl;
if (h.right != 0)
s.push(hf[h.right]);
if (h.left != 0)
s.push(hf[h.left]);
}
}
void HuffManDeCode(HuffTree hf, char code[], int len, int n)
{
HuffNode p = hf[len - 1];
for (int i = 0; i < n; i++)
{
if (code[i] == '0')
p = hf[p.left];
else
p = hf[p.right];
if (p.left == 0)
{
cout << p.weght << endl;
p = hf[len - 1];
}
}
}
char** HuffManCode(HuffTree hf, int len)
{
len /= 2;
char** Code = new char* [len];
for (int i = 1; i <= len; i++)
{
char str[10];
Code[i - 1] = new char[10];
int count = 0;
HuffNode p = hf[i],q;
while (p.parent != 0)
{
q = hf[p.parent];
if (hf[q.left].weght == p.weght)
str[count++] = '0';
else
str[count++] = '1';
p = q;
}
str[count] = '\0';
for (int j = 0, k = count - 1; j < count; j++, k--)
{
Code[i - 1][j] = str[k];
}
Code[i - 1][count] = '\0';
}
return Code;
}
int WPLHuffManTree(HuffTree hf,int len)
{
int wpl = 0;
for (int i = len / 2+1; i < len; i++)
{
wpl += hf[i].weght;
}
return wpl;
}