赫夫曼树

赫夫曼树又称最优树,是一类带权路径长度最短的树。

树

路径:由一结点到另一结点间的分支所构成

路径长度:路径上的分支数目 例如上面的a->e的路径长度=2

带权路径长度:结点到根的路径长度与结点上权的乘积

树的带权路径长度:结点到根的路径长度与结点上权的乘积

赫夫曼树:带权路径长度最小的树

赫夫曼树
上面这个图的树的值为WPL=7*2+5*2+2*2+4*2=36

赫夫曼树构造过程

基本思想:使权大的结点靠近根
操作要点:对权值的合并、删除、替换,总是合并当前值最小的两个

赫夫曼树的构造过程

  1. 根据给定的n个权值{w1,w2,w3,….wn},构造n棵只有根结点的二叉树。
  2. 在森林中选取两棵根结点权值最小的树作左右子树,构造一棵新的二叉树,置新二叉树根结点权值为其左右子树根结点权值之和。
  3. 在森林中删除这两颗树,同时将新得到的二叉树加入森林中。
  4. 重复上述两步,直到只含一棵树为止,这棵树即赫夫曼树。
    赫夫曼树构造过程

这里写图片描述

      //--------赫夫曼树的存储表示------
          typedef struct{
               int weight;
               int parent,lchild,rchild;
     }HTNode, *HuffmanTree;

赫尔曼构造算法的实现

  1. 初始化HT[1…2n-1]:lch=rch=parent=0

  2. 输入初始n个叶子结点:置HT[1…n]的weight值

  3. 进行以下n-1次合并,依次产生HT[i],i=n+1…2n-1:
    3.1.在HT[1…i-1]中选两个未被选过的weight最小的两个结点HT[s1]和HTs2
    3.2)修改HT[s1]和HT[s2]的parent值:parent=i
    3.3)置HT[i]:weight=HT[s1].weight+HT[s2].weight,lch=s1,rch=s2

        void CreatHuffmanTree(HuffmanTree &HT,int n)
        {
          //构造赫夫曼树HT
           if(n<=1)return;
              m=2*n-1;
           HT=new HTNode[m+1];//0号单元未用,所以需要动态分配m+1个单元,HT[m]表示根结点
           for(i=1;i<=m;++i)//将1~m号单元中的双亲、左孩子,右孩子的下标都初始化为0
           {
           HT[i].parent=0;HT[i].lchild=0;HT[i].rchild=0;
           }
           for(i=1;i<=n;++i)//输入前n个单元叶子结点的权值
           {
            cin>>HT[i].weight;
          }
           for(i=1;i<m;++i)  //通过n-1次·选择、删除、合并来创建赫夫曼树
           {
           Select(HT,i-1,s1,s2);
           //在HT[k](1≤k≤i-1)中选择两个其双亲域为0且权值为最小的结点
           //并返回它们在HT中序号s1和s2
    
           HT[s1].parent=i;
           HT[s2].parent=i;
           //得到新结点i,从森林中删除是s1s2的双亲域有0改为i
           HT[i].lchild=s1;//s1,s2分别作为i的左右孩子
           HT[i].rchild=s2;
           HT[i].weight=HT[s1].weight+HT[s2].weight;
           }
       }        
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值