首页 > 代码库 > Huffman Tree

Huffman Tree

 

哈弗曼树定义:给定n个权值作为n个叶子结点,构造一棵二叉树,若带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman Tree)。

哈夫曼树是带权路径长度最短的树,权值较大的结点离根较近。

#include<iostream> 
#include<iomanip> 
using namespace std;
const int n=5; //maxn表示叶子数目 
const int m=2*n-1; //m为森林中树的数
const int maxValue=http://www.mamicode.com/3555; //最大权值
struct TreeNode //哈夫曼树中的一个结点 
{ float weight; //权值 
int parent; //双亲
int lchild,rchild; //左孩子、右孩子
};

struct hacode //哈弗曼编码 
{ int bits[n+1]; //哈弗曼编码 
int start; //编码的存放位置
char ch; //所对应的字符
};

TreeNode haffTreeNode[m+1];
hacode code[n+1];

void CreatHaffTreeNode() //建立哈夫曼树 
{ 
int i,j,p1,p2; float s1,s2; 
for(i=1;i<=2*n-1;i++)
{ 
haffTreeNode[i].parent=0; 
haffTreeNode[i].lchild=0; 
haffTreeNode[i].rchild=0; 
haffTreeNode[i].weight=0; 
} 
cout<<"请输入"<<n<<"个权值"<<endl; 
for(i=1;i<=n;i++) 
cin>>haffTreeNode[i].weight; //输入权值 
for(i=n+1;i<=2*n-1;i++) //进行N-1次合并,n-1个非叶子节点
{ p1=p2=0;    //p1,p2分别指向两个权值最小的值的位置 
s1=s2=maxValue; //s1,s2代表两个最小权值 
for(j=1;j<=i-1;j++){ //选两个最小值 
if(haffTreeNode[j].parent==0) //该权值还没有选中 
if(haffTreeNode[j].weight<s1) 
{ 
s2=s1; 
s1=haffTreeNode[j].weight; 
p2=p1; 
p1=j; 
} 
else if(haffTreeNode[j].weight<s2) 
{
s2=haffTreeNode[j].weight;
p2=j;
} 
}//以下为合并 
haffTreeNode[p1].parent=i; 
haffTreeNode[p2].parent=i; 
haffTreeNode[i].lchild=p1; 
haffTreeNode[i].rchild=p2; 
haffTreeNode[i].weight=haffTreeNode[p1].weight+haffTreeNode[p2].weight; 
} 
}
void HuffCode() //哈弗曼编码 
{
hacode cd; 
int c,p;
for(int i=1;i<=n;i++) 
{ 
cd.start=n+1; 
cd.ch=96+i; //第一个树叶对应字母a,其余依此类推 
c=i; 
p=haffTreeNode[i].parent; 
while(p!=0) 
{ 
cd.start--; 
if(haffTreeNode[p].lchild==c) 
cd.bits[cd.start]=0; 
else 
cd.bits[cd.start]=1; 
c=p; 
p=haffTreeNode[p].parent; 
} 
code[i]=cd; 
} 
for(int i=1;i<=n;i++) 
{

cout<<"字符"<<code[i].ch<<"的权值为:"<<haffTreeNode[i].weight<<setw(5)<<"\t编码为:"; 
for(int j=code[i].start;j<=n;j++) 
cout<<code[i].bits[j]<<" "; 
cout<<endl; 
} 
} 
void TransCode() //哈弗曼译码 
{ 
int i=m; 
char b; 
cout<<"请输入二进制编码串(以非0,1结束)"<<endl; 
cin>>b; 
while((b==0)||(b==1)) 
{ 
if(b==0) 
i=haffTreeNode[i].lchild; 
else 
i=haffTreeNode[i].rchild; 
if(haffTreeNode[i].lchild==0) 
{ 
cout<<code[i].ch; 
i=m; 
}
cin>>b; 
} 
} 
void main() 
{ 
CreatHaffTreeNode(); //建立哈夫曼树 
HuffCode(); //实现哈弗曼编码 
TransCode(); //进行哈弗曼译码 
cout<<endl; 
system("pause");
}

 

Huffman Tree