#include<iostream>
#define LEN sizeof(HaffmanNode)
#define MAXSIZE 100
#define MAX 9999
using namespace std;
typedef struct{
int value;
int lChild,rChild,parent;
}HaffmanNode,Haffman[MAXSIZE];
typedef struct{
char name;
int w;
char code[MAXSIZE];
}HaffmanCode[MAXSIZE];
//全局变量
Haffman h;
HaffmanCode hc;
//筛选出值最小的两个结点,s1,s2存储其结点的索引位置
void Select(Haffman h,int index,int *s1,int *s2)
{
*s1=0;*s2=0;
for(int i=1;i<=index;i++)
{
//筛选出无双亲结点,且权值最小的两个结点
if(h[i].parent==0)
{
if(h[i].value<=h[*s1].value)
{
*s2=*s1;
*s1=i;
}
else if(h[i].value<h[*s2].value)
{
*s2=i;
}
}
}
}
//创建哈弗曼树及每个叶结点的哈弗曼编码
void CreateHaffmanTree(Haffman h,HaffmanCode hc,int n)
{
int s1,s2;
h[0].value=MAX;
for(int i=1;i<=n;i++)
{
h[i].lChild=h[i].rChild=h[i].parent=0;
h[i].value=hc[i].w;
}
for(i=n+1;i<=2*n-1;i++)
{
h[i].lChild=h[i].rChild=h[i].parent=h[i].value=0;
}
//构建叶子结点外的其他结点
for(i=n+1;i<=2*n-1;i++)
{
Select(h,i-1,&s1,&s2);
h[i].lChild=s1;h[i].rChild=s2;
h[i].value=h[s1].value+h[s2].value;
h[s1].parent=i;h[s2].parent=i;
}
}
//求每个叶结点的哈弗曼编码
void CreateHaffmanCode(Haffman h,HaffmanCode hc,int n)
{
int Stack[MAXSIZE],top=-1;
char flag[MAXSIZE],j;
HaffmanNode th;
for(int i=1;i<=n;i++)
{
th=h[i];int c=i;j=0;
while(th.parent!=0)
{
Stack[++top]=th.parent;
if(h[Stack[top]].lChild==c)
{
flag[top]='L';c=th.parent;
}
else if(h[Stack[top]].rChild==c)
{
flag[top]='R';c=th.parent;
}
th=h[Stack[top]];
}
while(top!=-1)
{
if(flag[top]=='L')
hc[i].code[j++]='0';
else
hc[i].code[j++]='1';
top--;
}
hc[i].code[j]='\0';
}
}
//求叶结点的所在层的深度
int Depth(Haffman h,HaffmanNode hd)
{
int count=0;
HaffmanNode temp;
temp=hd;
while(temp.parent!=0)
{
temp=h[temp.parent];
count++;
}
return count;
}
//打印叶结点的哈弗曼编码值,以及二叉树的带权路径长度
void PrintHaffmanCode(Haffman h,HaffmanCode hc,int n)
{
int weight,sum=0;
for(int i=1;i<=n;i++)
{
weight=Depth(h,h[i])*h[i].value;
cout<<"结点名称:"<<hc[i].name<<",结点的哈弗曼编码值:"<<hc[i].code<<"\n";
sum+=weight;
}
cout<<"带权路径长度为:"<<sum<<"\n";
}
int main()
{
int n;
char cmd;
do{
cout<<"输入叶子结点数目\n";
cin>>n;
cout<<"输入叶子结点名称和每个叶子结点的权值\n";
for(int i=1;i<=n;i++)
{
cin>>hc[i].name>>hc[i].w;
}
CreateHaffmanTree(h,hc,n);
CreateHaffmanCode(h,hc,n);
PrintHaffmanCode(h,hc,n);
cout<<"继续吗y/Y\n";
cin>>cmd;
}while(cmd=='y'||cmd=='Y');
return 0;
}
哈弗曼树建立与哈弗曼编码
最新推荐文章于 2021-01-29 10:00:04 发布
本文介绍了一种使用C++实现哈弗曼树及其编码的方法。通过定义结构体表示哈弗曼树节点,并利用筛选算法找到权值最小的两个节点进行连接,最终构建完整的哈弗曼树。此外,还实现了计算每个叶节点的哈弗曼编码,以及二叉树的带权路径长度。
2484

被折叠的 条评论
为什么被折叠?



