您的位置:首页 > 其它

哈夫曼树(Huffman tree)->一种二叉树

2017-01-22 17:57 597 查看
知识前提:

一棵树的路径长度为从树根到其余各节点的路径长度之和

结点的带权路径长度为从根结点到该结点之间的路径长度与该结点上所带权值的乘积

每个叶结点的带权路径长度之和就是这棵树的带权路径长度

哈夫曼树定义:

假设有n个权值,构造有n个叶子的二叉树,每个叶子的权值就是n个权值之一,这样可以构造很多个,其中一个是带权路径长度最小的,这棵二叉树就被称为哈夫曼树或最优二叉树

哈夫曼树的构造,用到最小堆:

必须使权值越大的叶结点越靠近根节点,提出一种贪心算法,在初始状态下,将每个元素看作一棵独立的树,每次选择权值最小的两棵树进行合并

对于同一组给定权值叶结点所构造的哈夫曼树,树的形状可能不同。但无论形状如何,这些哈夫曼树的带权路径长度是相同的,并且一定都是同一最小值

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
struct node{
int weight;
struct node *left;
struct node *right;
};
void PercolateDown(struct node *minHeap[],int loc,int *n){
int i,child;
struct node *temp=minHeap[loc];
for(i=loc;i*2<=*n;i=child){
child=i*2;
if(child+1<=*n&&minHeap[child+1]->weight<minHeap[child]->weight)
child++;
if(temp->weight>minHeap[child]->weight)
minHeap[i]=minHeap[child];
else
break;
}
minHeap[i]=temp;
}
void PercolateUp(struct node *minHeap[],int loc){
int i;
struct node *temp=minHeap[loc];
for(i=loc;i>1;i/=2){
if(minHeap[i/2]->weight>minHeap[i]->weight)
minHeap[i]=minHeap[i/2];
else
break;
}
minHeap[i]=temp;
}
struct node *DeleteMin(struct node *minHeap[],int *n){
struct node *temp=minHeap[1];
minHeap[1]=minHeap[(*n)--];
PercolateDown(minHeap,1,n);
return temp;
}
void Insert(struct node *minHeap[],struct node *temp,int *n){
minHeap[++(*n)]=temp;
PercolateUp(minHeap,*n);
}
void BuildHeap(struct node *minHeap[],int *n){
for(int i=*n/2;i>=1;i--){
PercolateDown(minHeap,i,n);
}
}
struct node *BuildHuffman(struct node *minHeap[],int *n){
int t=*n;
struct node *temp,*Huffman;
for(int i=1;i<t;i++){
temp=(struct node *)malloc(sizeof(struct node));
temp->left=DeleteMin(minHeap,n);
temp->right=DeleteMin(minHeap,n);
temp->weight=temp->left->weight+temp->right->weight;
Insert(minHeap,temp,n);
}
return DeleteMin(minHeap,n);
}
void InOrderTraversal(struct node *Huffman){
if(Huffman==NULL)
return;
InOrderTraversal(Huffman->left);
cout<<' '<<Huffman->weight;
InOrderTraversal(Huffman->right);
}
int main(){
int size,temp;
struct node *minHeap[100];
struct node *Huffman;
cin>>size;
for(int i=1;i<=size;i++){
cin>>temp;
minHeap[i]=(struct node *)malloc(sizeof(struct node));
minHeap[i]->weight=temp;
minHeap[i]->left=NULL;
minHeap[i]->right=NULL;
}
BuildHeap(minHeap,&size);
Huffman=BuildHuffman(minHeap,&size);
InOrderTraversal(Huffman);
return 0;
}

应用:哈夫曼编码

又称“前缀编码”,为了不产生二义性,任何一个字符的编码都不能是另一个字符编码的前缀
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: