哈夫曼树又称最优二叉树,是一种带权路径长度最短的二叉树。所谓树的带权路径长度,就是树中所有的叶结点的权值乘上其到根结点的路径长度的乘积之和。哈弗曼编码是它的重要应用,哈弗曼编码是一种无前缀编码。
假设计算机世界里文字只由由A、B、C、D、E四个字符组成,它们出现的频率分别为5,4,3,2,1,那么我们第一步先取两个最小权值作为左右子树构造一个新树,即取1,2构成新树,其结点为1+2=3,如图:
虚线为新生成的结点,第二步再把新生成的权值为3的结点放到剩下的集合中,所以集合变成{5,4,3,3},再根据第二步,取最小的两个权值构成新树,如图:
再依次建立哈夫曼树,如下图:
其中各个权值替换对应的字符即为下图:
所以各字符对应的编码为:A->11,B->10,C->00,D->011,E->010
霍夫曼编码是一种无前缀编码。解码时不会混淆。其主要应用在数据压缩,加密解密等场合。
(以上来自网络,接下来进入正题编码,创建二叉树后,用前序遍历粗略检测)
以下代码为原创
输入:
5
1 2 3 4 5
输出:15 6 3 3 1 2 9 4 5
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<time.h>
typedef int Weight;
typedef struct Tnode
{
Weight weight;
struct Tnode *left,*right;
}*Ptnode;
typedef Ptnode Huffman;
///
typedef Ptnode Ele;
const Ele ERROR=NULL;
typedef struct Hnode
{
Ele *data;
int size;
int maxsize;
}*heap;
typedef heap Minheap;
Minheap createMinheap(int maxsize){
Minheap h=(Minheap)malloc(sizeof(struct Hnode));
h->data=(Ele*)malloc(sizeof(Ele)*(maxsize+1));
h->size=0;
h->maxsize=maxsize;
return h;
}
void freeMinheap(Minheap h){
if(h!=NULL){
free(h->data);
free(h);
}
h=NULL;
}
bool isfull(Minheap h){
return h->size>=h->maxsize;
}
bool isempty(Minheap h){
if(h){
return h->size==0;
}
}
void insert(Minheap h,Ele e){
if(isfull(h))
{printf("full\n");return;}
int i=++h->size;
for(;i>1&&h->data[i/2]->weight>e->weight;i/=2){
h->data[i]=h->data[i/2];
}
h->data[i]=e;
}
Ele del(Minheap h){
if(isempty(h))
{printf("emtpy\n");return ERROR;}
Ele min=h->data[1];
Ele tmp=h->data[h->size--];
int i=1,childmin;
for(;2*i<=h->size;i=childmin){
childmin=2*i;
if(h->data[childmin]->weight>h->data[childmin+1]->weight)
childmin++;
if(tmp->weight<=h->data[childmin]->weight)break;
h->data[i]=h->data[childmin];
}
h->data[i]=tmp;
return min;
}
Ptnode newNode(){
Ptnode ptnode=(Ptnode)malloc(sizeof(struct Tnode));
ptnode->left=NULL;
ptnode->right=NULL;
return ptnode;
}
Huffman createHuffman(int n){
Huffman huff=NULL;
Minheap h=createMinheap(n);
Weight weight;
Ptnode leftnode,rightnode,newnode;
for(int i=0;i<n;i++)
{scanf("%d",&weight);
newnode=newNode();
newnode->weight=weight;
insert(h,newnode);
}
for(int i=0;i<n-1;i++){
leftnode=del(h);
rightnode=del(h);
newnode=newNode();
newnode->weight=leftnode->weight+rightnode->weight;
newnode->left=leftnode;
newnode->right=rightnode;
insert(h,newnode);
}
huff=del(h);
freeMinheap(h);
return huff;
}
void pr(Huffman h){
if(h){
printf("%d ",h->weight );
pr(h->left);
pr(h->right);
}
}
int main(){
int n=0;
scanf("%d",&n);
Huffman huff=createHuffman(n);
pr(huff);
}