哈夫曼树的建立以及编码

哈夫曼树的原理结论带权路径长度WPL最小的二叉树(WPL:从根到某点的长度与该点的权值相乘的所有点的和)哈夫曼树的节点数=2*叶子数-1(叶子数就是你输入的点数)哈夫曼树的构造方式从叶子选择权值最小的两个点组成一个节点将组合的这两个节点的父亲节点指向你组成的这个节点将你组成的节点的左右儿子节点指向这两个点(小的在左 大的在右)将该节点的权值加入叶子中重复1哈夫曼编码从根节点开始到该点的距离就代表你编码的长度左儿子的编码单元是0 右儿子的编码单元是1从根节点到该点的所有点的编
摘要由CSDN通过智能技术生成

哈夫曼树的原理结论

  1. 带权路径长度WPL最小的二叉树(WPL:从根到某点的长度与该点的权值相乘的所有点的和)
  2. 哈夫曼树的节点数=2*叶子数-1(叶子数就是你输入的点数)

哈夫曼树的构造方式

  1. 从叶子选择权值最小的两个点组成一个节点
  2. 将组合的这两个节点的父亲节点指向你组成的这个节点
  3. 将你组成的节点的左右儿子节点指向这两个点(小的在左 大的在右)
  4. 将该节点的权值加入叶子中
  5. 重复1

哈夫曼编码

  1. 从根节点开始到该点的距离就代表你编码的长度
  2. 左儿子的编码单元是0 右儿子的编码单元是1
  3. 从根节点到该点的所有点的编码组合起来就是该点的编码

接下来 就是代码时间了

哈夫曼树的构造

  1. 我们首先来看看树的结构体是啥样的:
typedef struct node
{
   
 char data;//存储叶子的名字 
 int weight; //存储权值 
 int parent; //存储父亲节点 
 int lchild,rchild;//存储左右儿子节点 
 int longs;//存储根到该节点的距离 
 char m;//存储该点的一个编码 
}Node;
typedef struct tree
{
   
 node *elem;
 int leaf;//存储叶子的个数 
}Tree;
  1. 我们肯定得初始化吧:
void init(tree &HT)//初始化 
{
   
 cout<<"输入叶子个数 :"<<endl;
 cin>>HT.leaf;
 HT.elem=(node *)malloc((2*HT.leaf)*sizeof(node));//分配空间 
 cout<<"输入名称:"<<endl;
 for(int i=1;i<=HT.leaf;i++)
 {
   
  cin>>HT.elem[i].data;
 }
 cout<<"输入权重:"<<endl;
 for(int i=1;i<=HT.leaf;i++)
 {
   
  cin>>HT.elem[i].weight;
 }
 for(int i=1;i<=2*HT.leaf-1;i++)
 {
   
  HT.elem[i].parent=HT.elem[i].lchild=HT.elem[i].rchild=HT.elem[i].longs=0;//初始化 
  if(i>=HT.leaf+1)
  {
   
   HT.elem[i].data=HT.elem[i].weight='\0';
  }
 } 
}
  1. 终于开始构造哈夫曼树,首先我们要先找到最小的两个点:
if(HT.elem[i].weight<min1)//比较过程 
    {
      
        min2=min1;//min1 min2 是很大的数 方便第一次找最小值
        m2=m1;//m1 m2 是记录这两个最小点的序号 方便后面的指向
     min1=HT.elem[i].weight;
     m1=i;
    }
    else if(HT.elem[i].weight<min2)
    {
   
     min2=HT.elem[i].weight;
     m2=i;
       } 

然后 我们得做什么 对 我们要把这两个点组合 并且将他们的指向完成(注意 我这里的写法是为了方便待会做编码 才有的m 所以可以忽略):

HT.elem[k].weight=min
  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值