#include <string>
#include <string.h>
using namespace std;
// 哈夫曼树存储结构定义
typedef struct {
int weight;
int parent,lchild,rchild;
} HTNode, *HuffmanTree;
// 哈夫曼编码存储结构定义
typedef char **HuffmanCode;
void Select(HuffmanTree HT, int len, int &s1, int &s2) {
int i, min1 = 0x3f3f3f3f, min2 = 0x3f3f3f3f; //先赋予最大值
for (i = 1; i <= len; i++) {
if (HT[i].weight < min1 && HT[i].parent == 0) {
min1 = HT[i].weight;
s1 = i;
}
}
int temp = HT[s1].weight; //将原值存放起来,然后先赋予最大值,防止s1被重复选择
HT[s1].weight = 0x3f3f3f3f;
for (i = 1; i <= len; i++) {
if (HT[i].weight < min2 && HT[i].parent == 0) {
min2 = HT[i].weight;
s2 = i;
}
}
HT[s1].weight = temp; //恢复原来的值
}
//用算法5.10构造赫夫曼树
void CreatHuffmanTree(HuffmanTree &HT, int n) {
//构造赫夫曼树HT
if(n<=1) return;
int m=2*n-1;
HT=new HTNode[m+1];
for(int i=1;i<=m;i++)
{HT[i].parent=0;
HT[i].lchild=0;
HT[i].rchild=0;}
for(int i=1;i<=n;++i)
cin>>HT[i].weight;
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;
}
}
// CreatHuffmanTree
void CreatHuffmanCode(HuffmanTree HT, HuffmanCode &HC, int n) {
//从叶子到根逆向求每个字符的赫夫曼编码,存储在编码表HC中
HC=new char*[n+1];
char*cd=new char[n];
cd[n-1]='\0';
for(int i=1;i<=n;i++){
int start=n-1;
int c=i;
int f=HT[i].parent;
while(f!=0){
--start;
if(HT[f].lchild==c) cd[start]='0';
else cd[start]='1';
c=f;f=HT[f].parent;
}
HC[i]=new char[n-start];
strcpy(HC[i],&cd[start]);
}
delete cd;
}// CreatHuffanCode
void show(HuffmanTree HT, HuffmanCode HC) {
for (int i = 1; i <= sizeof(HC); i++)
cout << HT[i].weight << "编码为" << HC[i] << endl;
}
int main() {
HuffmanTree HT;
HuffmanCode HC;
int n;
cout << "请输入叶子结点的个数:\n";
cin >> n; //输入赫夫曼树的叶子结点个数
CreatHuffmanTree(HT, n);
cout << "哈夫曼树创建成功……" << endl;
CreatHuffmanCode(HT, HC, n);
cout << "字符编码完成……" << endl;
show(HT, HC);
}
cpp
在这里插入代码片
哈夫曼树的创建
最新推荐文章于 2024-07-24 22:13:06 发布