//
// Created by dgm on 19-3-16.
//
#include <iostream>
#include <cstring>
using namespace std;
typedef struct HNode{
HNode(int w,int p,int l,int r)
:weight(w),
parent(p),
lchild(l),
rchild(r)
{}
unsigned int weight;
unsigned int parent,lchild,rchild;
}HNode,*HuffmanTree;
typedef char** HuffmanCode; //保存n个huffman编码
void Select(HuffmanTree HT,int n,int &s1,int &s2) //从未被合并过得元素中找到权值最小的两个
{
for (int i = 1; i <= n; ++i) {
if(!HT[i].parent){
s1=i;break;
}
}
for (int i = s1+1; i <= n; ++i) {
if(!HT[i].parent){
s2=i;break;
}
}
for (int i = s2; i <= n; ++i) {
if(!HT[i].parent&&HT[i].weight<=HT[s1].weight){
s2=s1;s1=i;
}
}
}
void HuffmanCoding(HuffmanTree&HT,HuffmanCode&HC,int *w,int n)
{
int m=2*n-1;
HT=(HuffmanTree)malloc((m+1)* sizeof(HNode)); //分配空间,由于第一个元素保存在HT[1]而非HT[0]中,
//所以申请m+1个空间
HuffmanTree p;
int i=0;
for (i=1,p=HT+1;i<=n;i++,p++,w++) *p={*w,0,0,0}; //元素保存在叶子节点中(编号1-n)
for (;i<=m;i++,p++) *p={0,0,0,0}; //非叶节点(n+1-m)
for (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;
}
//到这里,树就建好了,接下来遍历这个数得到叶子节点的编码
HC=(HuffmanCode)malloc((n+1)* sizeof(char*)); //HC[i]存储第i个元素的编码
char *cd=(char*)malloc(n* sizeof(char)); //cd作临时变量,记录编码后存入HC
for (i=1; i<=n; i++) {
cd[n-1]='\0'; //后边的strcpy是以cd[start]的地址为参数,所以要标记结束位置
int c,f;
int start=n-1;
//下边是从树的最底层(或者叶子)回到根节点,并在这个过程中得到编码
for (c=i,f=HT[i].parent; f; c=f,f=HT[f].parent) {//从第一个元素开始
if (HT[f].lchild==c)cd[--start]='0'; //如果元素是爸爸的左孩子,则标0
else cd[--start]='1'; //如果是右孩子,则标1
//因为是从叶子到根,所以--start(前置--),这样以后,按从cd[start]到cd[n-1]的顺序
//得到的恰好是按从根到叶子的编码(而不是从叶子到根)
}
HC[i]=(char*)malloc((n-start)* sizeof(char)); //实际编码位数所需空间
strcpy(HC[i],&cd[start]); //复制到HC[i]
}
free(cd); //过河拆桥
for (i = 1; i <= n; ++i) { //输出看看,应该正确
cout<<"the Huffman Code of "<<i<<" is "<<HC[i]<<endl;
}
}
int main()
{
//这里为了简便,将元素的值和权重设成一样的了,
//也可以用一个结构体分别保存值和权重(例如值为E,权重为0.7)
//然后按照权重对值进行编码
int n=5;
int *w;
for (int i = 1; i <= n; ++i) {
w[i]=i;
}
HuffmanTree HT;
HuffmanCode HC;
HuffmanCoding(HT,HC,w,n);
return 0;
}
哈夫曼树(Huffman Tree)
最新推荐文章于 2020-06-03 14:53:17 发布