C++实现哈夫曼树算法
#include <iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<iomanip>
#pragma warning(disable : 4996)
using namespace std;
typedef struct
{
int weight;
int parent, lchild, rchild;
} htnode, * huffmantree;
typedef char** huffmancode;
typedef char* huffmancoder;
void select(huffmantree ht, int i, int& s1, int& s2)
{
int w1 = 0, w2 = 0;
for (int j = 1; j <= i; j++)
{
if (ht[j].parent == 0)
{
if (w1 == 0)
{
w1 = ht[j].weight;
s1 = j;
}
else if (w2 == 0)
{
w2 = ht[j].weight;
s2 = j;
if (w1 > w2)
{
int t = w1;
w1 = w2;
w2 = t;
t = s1;
s1 = s2;
s2 = t;
}
}
else if (ht[j].weight < w2)
{
if (ht[j].weight < w1)
{
w2 = w1;
s2 = s1;
w1 = ht[j].weight;
s1 = j;
}
else
{
w2 = ht[j].weight;
s2 = j;
}
}
}
}
if (s1 > s2)
{
int t = s1;
s1 = s2;
s2 = t;
}
}
void puttree(huffmantree ht, int n)
{
for (int i = 1; i <= n; i++)
{
cout << setw(8) << ht[i].weight
<< setw(8) << ht[i].parent
<< setw(8) << ht[i].lchild
<< setw(8) << ht[i].rchild << endl;
}
cout << "--------------------------------" << endl;
}
void putcode(huffmancode hc, int n)
{
cout << "Huffman tree编码:" << endl;
for (int i = 1; i <= n; i++)
{
cout << i << " " << hc[i] << endl;
}
cout << "--------------------------------" << endl;
}
void huffmancoding(huffmantree& ht, huffmancode& hc, int* w, int n)
{
if (n <= 1)
return;
int m = 2 * n - 1;
ht = new htnode[m + 1];
huffmantree p = ht;
int i = 1;
for (; i <= n; i++, w++)
{
p[i].weight = *w;
p[i].parent = 0;
p[i].lchild = 0;
p[i].rchild = 0;
}
for (; i <= m; i++)
{
p[i].weight = 0;
p[i].parent = 0;
p[i].lchild = 0;
p[i].rchild = 0;
}
cout << "Huffman tree的存储格式(初始状态):" << endl;
puttree(ht, m);
for (int i = n + 1; i <= m; i++)
{
int s1, s2;
select(ht, i - 1, s1, s2);
ht[s1].parent = i;
ht[s2].parent = i;
ht[i].lchild = s1;
ht[i].rchild = s2;
ht[i].weight = ht[s1].weight + ht[s2].weight;
}
cout << "Huffman tree的存储格式(终止状态) :" << endl;
puttree(ht, m);
hc = new huffmancoder[n + 1];
char* cd = new char[n];
cd[n - 1] = '\0';
for (int i = 1; i <= n; i++)
{
int start = n - 1;
int f = ht[i].parent;
for (int c = i; f != 0; c = f, f = ht[f].parent)
if (ht[f].lchild == c)
cd[--start] = '0';
else
cd[--start] = '1';
hc[i] = new char[n - start];
strcpy(hc[i], &cd[start]);
}
delete[] cd;
putcode(hc, n);
}
void codemodal(huffmantree ht, char* code, int m)
{
int ch = m, j = 0;
int quan[100], xun[100];
for (int i = 0; code[i] != '\0'; i++)
{
if (ht[ch].lchild == 0 && ht[ch].rchild == 0)
{
quan[j] = ht[ch].weight;
xun[j] = ch;
j++;
ch = m;
i--;
}
else if (code[i] == '0')
ch = ht[ch].lchild;
else
ch = ht[ch].rchild;
}
int i = 0;
cout << "解码后对应的序号:" << endl;
while (i < j)
{
cout << xun[i] << " ";
i++;
}
cout << endl;
cout << "解码后对应的权值:" << endl;
i = 0;
while (i < j)
{
cout << quan[i] << " ";
i++;
}
}
int main()
{
huffmantree ht;
huffmancode hc;
int* w;
int n;
cout << "请输入Huffman tree的大小:" << endl;
cin >> n;
w = new int[n + 1];
cout << "请输入Huffman tree的权值:" << endl;
int i = n;
int* p = w;
while (i--)
{
cin >> *p;
p++;
}
huffmancoding(ht, hc, w, n);
char* code;
int l;
cout << "请输入01编码的长度:" << endl;
cin >> l;
w = new int[l + 1];
cout << "请输入01编码集:" << endl;
i = 0;
code = new char[l + 1];
char* q = code;
while (i != l)
{
cin >> q[i];
i++;
}
q[i] = '\0';
codemodal(ht, code, 2 * n - 1);
return 0;
}
专心看人间!
浙公网安备 33010602011771号