最小堆的应用之哈弗曼树5.2

哈夫曼树又称最优二叉树,是一种带权路径长度最短的二叉树。所谓树的带权路径长度,就是树中所有的叶结点的权值乘上其到根结点的路径长度的乘积之和。哈弗曼编码是它的重要应用,哈弗曼编码是一种无前缀编码。


假设计算机世界里文字只由由A、B、C、D、E四个字符组成,它们出现的频率分别为5,4,3,2,1,那么我们第一步先取两个最小权值作为左右子树构造一个新树,即取1,2构成新树,其结点为1+2=3,如图:

12

虚线为新生成的结点,第二步再把新生成的权值为3的结点放到剩下的集合中,所以集合变成{5,4,3,3},再根据第二步,取最小的两个权值构成新树,如图:

13

再依次建立哈夫曼树,如下图:

14

其中各个权值替换对应的字符即为下图:

15

所以各字符对应的编码为: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);
}








  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值