哈夫曼编码代码流程
1.创建一个优先队列,将所有的符号及其频率加入队列中。
2.从队列中取出两个频率最低的结点,合并生成一个新的结点,频率为两者之和。
3.将新节点插入队列中。
4.构建出哈夫曼树后,对树进行遍历,左分支编码为0,右分支编码为1,得到每个符号的哈夫曼编码。
5.使用得到的哈夫曼编码对原始数据进行编码。
构造原理:
#include<stdio.h>
#include<stdlib.h>
#include<iostream>
using namespace std;
typedef struct{
int weight;
int parent,lchild,rchild;
}HTNode,*HuffmanTree;
//筛选函数
void Select(HuffmanTree HT,int len,int &s1,int &s2)
{
int i,min1=32767,min2=32767;
for(int i;i<=len;i++)
{
if(HT[i].weight<min1&&HT[i].parent==0)
{
s2=s1;
min2=min1;
min1=HT[i].weight;
s1=i;
}
else if(HT[i].weight<min2&&HT[i].parent==0)
{
min2=HT[i].weight;
s2=i;
}
}
}
//构建哈夫曼树
void CreatHuffmanTree(HuffmanTree &HT,int n)
{
//m表示哈夫曼树的总结点个数,s1,s2分别表示当前最小、第二小的结点
int m,s1,s2,i;
if(n<=1) return;
//开局n个权值,然后两两组合的过程中会产生n-1个新的数字,所以开辟2n-1个数组存放
m=2*n-1;
HT=new HTNode[m+1];
for(i=1;i<=m;++i)
{
HT[i].parent=0;
HT[i].lchild=0;
HT[i].rchild=0;
}
//给N个权值赋值
for(i=1;i<=n;++i)
{
cin>>HT[i].weight;
}
for(i=n+1;i<=m;++i)
{
Select(HT,i,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;
}
}
//遍历哈夫曼树
void print(HuffmanTree HT,int n)
{
for(int i=1;i<=2*n-1;i++)
cout<<HT[i].weight<<" "<<HT[i].parent<<" "<<HT[i].lchild<<" "<<HT[i].rchild<<endl;
}
int main()
{
HuffmanTree HT;
int n;
cin>>n;
CreatHuffmanTree(HT,n);
print(HT,n);
return 0;
}