哈夫曼编码实现
我是看着数据结构(清华大学那本)


这两页说明了编码方式的重要性
我想说的是书上,没说清楚,代码有些实现的细节自己搞了
代码
#include<iostream>
#include<malloc.h>
#include<stdlib.h>
#include<string.h>
#include<cstdio>
#include<string>
#include<algorithm>
using namespace std;
const int N = 1e3 + 10;
bool vis[N];
typedef struct
{
int weight;
int parent, lchild, rchild;
}HTNode, * HuffmanTree;
typedef char** Huffmancode;
int now = 0;
void Select(HuffmanTree& HT, int cur, int& s1, int& s2, int n)
{
now++;
int val = 1e6;
int a, b;
for (int i = 1; i <= cur; i++)
{
if (vis[i]) continue;//如果用过了就不可以用了
if (HT[i].weight < val)
{
val = HT[i].weight;
a = i;
}
}
s1 = a;
vis[a] = 1;
val = 1e6;
for (int i = 1; i <= cur; i++)
{
if (vis[i]) continue;
if (HT[i].weight < val)
{
val = HT[i].weight;
b = i;
}
}
s2 = b;
vis[b] = 1;
//cout << now << " " << s1 << " " << s2 << endl;
if (a > n&& b <= n) swap(s1, s2);//这里必须注意,必须把1到 n放在叶子结点
}
void Huffmancoding(HuffmanTree& HT, Huffmancode& HC, int* w, int n)
{
if (n <= 1) return;
int m = 2 * n - 1;
HT = (HuffmanTree)malloc((m + 1) * sizeof(HTNode));//0号不用
int i;
for (i = 1; i <= n; ++i)
HT[i] = { w[i],0,0,0 };
for (; i <= m; ++i)
HT[i] = { 0,0,0,0 };
for (i = n + 1; i <= m; ++i)
{
int s1, s2;
Select(HT, i - 1, s1, s2, n);//书上没写这个函数,
HT[s1].parent = i, HT[s2].parent = i;
//统一把小的放在左边,书上的不一致p148那个图有问题
HT[i].lchild = s1, HT[i].rchild = s2;
HT[i].weight = HT[s1].weight + HT[s2].weight;
}
//从叶子结点到根逆向求每个字符的哈夫曼编码
//分配n个字符编码的头指针向量
HC = (Huffmancode)malloc((n + 1) * sizeof(char*));
//分配求编码的工作空间
char* cd = (char*)malloc(n * sizeof(char));
cd[n - 1] = '\0';
int cur, f, start;
for (i = 1; i <= n; i++)
{
int cnt = n - 1;
//cout << i << endl;
for (cur = i, f = HT[i].parent; f != 0; cur = f, f = HT[f].parent)
{
// cout << f << " ";
if (HT[f].lchild == cur) cd[--cnt] = '0';
else cd[--cnt] = '1';
}
//puts("");
HC[i] = (char*)malloc((n - cnt) * sizeof(char));
strcpy(HC[i], &cd[cnt]);//从cnt这个地方开始复制
}
free(cd);
}
int main()
{
int n;
int a[100];
memset(vis, 0, sizeof(vis));
HuffmanTree HT;
Huffmancode HC;
cin >> n;
for (int i = 1; i <= n; i++)
cin >> a[i];
Huffmancoding(HT, HC, a, n);
for (int i = 1; i <= n; i++)
{
cout << i << " " << a[i] << " " << HC[i] << endl;
}
return 0;
}
//8
//5 29 7 8 14 23 3 11

浙公网安备 33010602011771号