我是看着數據結構(清華大學那本)


這兩頁說明了編碼方式的重要性
我想說的是書上,沒說清楚,代碼有些實現的細節自己搞了
代碼
#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
