zoukankan      html  css  js  c++  java
  • 19哈夫曼树

    哈夫曼树

    定义:给定n个正实数w1至wn,使权WPL(T)达最小值的树,称为哈夫曼树(最优二叉树)。(其中n表示该树中叶结点的数目,wk和lk(k=1,2,···,n)分别表示叶结点ik的权值和从树根到叶结点ik之间的路径长度。)

    注意:哈夫曼树必是正则二叉树!

    下面还要明白几个重要的概念:

    1. 叶的路径长度:指从根结点到叶结点的路径上的边数。

     

    2. 叶的加权路径长度:设二叉树T具有n片叶子,n个正实数w1至wn作为各叶的权,根到第i(1≤i≤n)片叶子的路径长度为li,那么,Wi*li称为该叶的加权路径长度。

     

    3. 二叉树T的权:n片叶子加权路径长度之和称为二叉树T的权WPL(T)。

     计算公式:

    此时,要注意, 加权路径长度为最小的二叉树不是唯一。在构建哈夫曼树时,相同的数值,可能会出现不同的哈弗曼树,但是都是最小路径。

    哈夫曼算法的描述:自底向上,逐步合并。

    具体步骤:

    步骤1)构造n棵单叶结点的二叉树,构成初始森林。将权w1~wn依次赋给各叶。

    步骤2)按下述步骤,反复将森林中的两棵树合并成一棵树,直到森林中只有一棵树,这棵树就是哈夫曼树。

    ①在森林中找出根的权最小的两棵树:T1和T2。

    ②将T1,T2合并成一棵树T,使T1,T2分别作为T的左右子树,且使T之根的权等于T1,T2之根的权之和。

    ③把合并树T加入森林。

    示例:

    构造哈夫曼树的源代码:
    (1)有关定义
    #include  <stdio.h>
    #define  n  XX    //XX为具体叶子数目
    #define  MAX  YYY    //YYY代表无穷大值,用作监督元
    #define  NULL  0        //空链域值
    typedef  struct  Hfnode    //结点类型
    {  int  data;            //权值域,假定为int类型
       struct  Hfnode  *Lson, *Rson, *next;  //儿子链域和森林链域
    }  Hfnode,*Hfptr;
    
    结点类型定义:
    typedef  struct  Hfnode   //  结点类型
     {  
      int  data;  //权值域,假定为int类型
       struct  Hfnode  *Lson, *Rson, *next; 
     } Hfnode,*Hfptr;
    主控函数:
    void  Hfmain( )  
     { 
       Hfptr Hroot,head; 
        head=inition( );  //调用初始化函数
        Hroot=creatHftree( );//调用造树函数
       ……  //其它处理
      }
    初始化函数:
    Hfptr  inition( )
      { 
    int i; 
    Hfptr h,p;
       h=p=new Hfnode;
       h->data=MAX;   //构造监督元结点 
       for(i=1;i<=n;i++)
         {  
        p->next=new Hfnode; 
            p=p->next;  //p始终指向当前尾结点 
            p->Lson=p->Rson=NULL; //做叶结点
            scanf("%d",&p->data); //读入叶之权wi
          }
    .   p->next=h;  //构成循环链
        return  h;
      }
    构造哈夫曼树的函数:
    Hfptr  creatHftree(Hfptr  head) 
      {
      int i;
      Hfptr  p,q,r,t1,t2;  
        for(i=1;i<n;i++) //进行n-1遍合并
      {
        r=new Hfnode; // 申请新根
          t1=head->next; // t1,t2指向两棵权最小的树根
          t2=t1->next;   
          r->data=t1->data+ t2->data; //权值相加
          r->Lson=t1; // t1,t2作新根r的左右儿子
          r->Rson=t2;
          head->next=t2->next;  //森林中删去t1,t2
          q=head; //准备进行有序插入
          p=head->next; //p是搜索指针,q是p的前趋
          while(1) //循环的为r寻找有序位置 
              {
            if(p->data<r->data)
               { 
              q=p;  
              p=p->next; 
            } //尚未找到时,继续循环
                else
                { 
               r->next=p; //找到后,插入r
                   q->next=r;
                   break;
                 }   
          }
        } //终止语句1 的for循环
         p=head->next; 
        delete  head;  //删去监督元
         return  (p);  //返回Huffmam树之根
       }  //构造完毕
  • 相关阅读:
    Python len() 方法
    Python join() 方法
    Python isupper() 方法
    使用quartz进行容器启动时登陆接口服务器和接口服务器进行心跳连接
    实现锁死的有滚动条的div的表格(datagird)
    使用spring的事务的三种方法
    webservice系统学习笔记7-使用handler实现过滤器/拦截器效果
    webservice系统学习笔记7-异常处理
    webservice系统学习笔记6-使用soap的header传递消息
    JSTL fmt:formatNumber 数字、货币格式化
  • 原文地址:https://www.cnblogs.com/gd-luojialin/p/8509337.html
Copyright © 2011-2022 走看看