SlideShare a Scribd company logo
1 of 29
Download to read offline
6.8 哈 夫 曼 树 与
        哈 夫 曼 编 码
•       最优树 ( 哈夫曼树 ) 的定
    义
•       如何构造最优树
•       前缀编码
•       哈夫曼编码
一、最优树的定义
结点的路径长度定义为:
  从根结点到该结点的路径上
  分支的数目。
树的路径长度定义为:
  树中每个结点的路径长度之和。
 结点的带权路径长度定义为:
  从根结点到该结点的路径长度与
  结点上权的乘积。
树的带权路径长度定义为:
  树中所有叶子结点的带权路径长度之和
 WPL(T) = Σwklk ( 对所有叶子结点 ) 。
 例如:

  在所有含 n 个叶子结点、并带相同权
值的 m 叉树中,必存在一棵其带权路径
长度取最小值 的树,称为“ 最优树”。
WPL(T)=    WPL(T)=    WPL(T)=
7×2+5×2+   7×3+5×3+   7×1+5×2+
2×2+4×2    4×2+2×1    2×3+4×3
 =36        =46       =35
二、如何构造最优树
  ( 哈夫曼算法 ) 以二叉树为例:
(1)  根据给定的 n 个权值 {w1, w2,
…, wn} ,构造 n 棵二叉树的集合
   F = {T1, T2, … , Tn} ,
其中每棵二叉树 Ti 中均只含一个带
权值
为 wi 的根结点,其左、右子树为空
(2)在 F 中选取其根结点的权值为最
 小的两棵二叉树,分别作为左、
 右子树构造一棵新的二叉树,并
 置这棵新的二叉树根结点的权值
 为其左、右子树根结点的权值之
 和;
(3) 从 F 中删去这两棵树,同时加入
      刚生成的新树;

(4)    重复 (2) 和 (3) 两步,直至
F 中只
含一棵树为止。这棵树便是哈夫
例如 : 已知权值 W={ 5, 6, 2, 9, 7 }
   5   6       2       9       7

   6   9       7           7
                       5        2

   9       7                   13
       5           2       6        7
9       7                 13
    5       2        6         7

                     29

            13                 16

        6        7        9         7
                               5        2
注意
:
•    ① 初始森林中的 n 棵二叉树,
  每棵树有一个孤立的结点,它们既
  是根,又是叶子
      ② n 个叶子的哈夫曼树要经过
  n- 1 次合并,产生 n- 1 个新结点。
  最终求得的哈夫曼树中共有 2n- 1
  个结点。
      ③ 哈夫曼树是严格的二叉树,
前缀编码
   在电文传输中,需要将电文中出现的
每个字符进行二进制编码。在设计编码时
需要遵守两个原则:
( 1 )发送方传输的二进制编码,到接收方
 解码后必须具有唯一性,即解码结果与发
 送方发送的电文完全一样;
( 2 )发送的二进制编码尽可能地短。下面
 我们介绍两种编码的方式。
1. 等长编码
      这种编码方式的特点 :
   每个字符的编码长度相同。
   设字符集只含有 4 个字符
A,B,C ,D,
用两位二进制表示的编码分别为
00 , 01 , 10 ,
11 。若现在电文为: A B A C C D A ,
则应发送二进制序列:
00010010101100 ,
总长度为 14 位。当接收方接收到这段电
文后,
将按两位一段进行译码。
2. 不等长编码
          在传送电文时,为了使其二
进制位数尽
可能地少,可以将每个字符的编码设计为不等
长
的,使用频度较高的字符分配一个相对比较短
的
编码,使用频度较低的字符分配一个比较长的
编
码。例如,可以为 A , B , C , D 四个字符
分别分配
0 , 00 , 1 , 01 ,并可将上述电文用二进制
序列:
哈夫曼编
码
  利用哈夫曼树可以构造一种不
等长的二进制编码,并且构造所得
的哈夫曼编码是一种最优前缀编码
,即使所传电文的总长度最短。称
为哈夫曼编码
哈夫曼编码的构造方法 :
( 1 )利用字符集中每个字符的使
 用
频率作为权值构造一个哈夫曼树;
( 2 )从根结点开始,为到每个叶
 子
结点路径上的左分支赋予 0 ,右分
 支
例如:

   假设有一个电文字符集中有 8 个字符,每
  个字符
的使用频率分别为
  {0.05,0.29,0.07,0.08,0.14,0.23,
0.03,0.11} ,现以此为例设计哈夫曼编码。
     为方便计算,将所有字符的频度乘以
  100 ,使
其转换成整型数值集合,得到
  { 5, 29, 7, 8, 14, 23,
100
               0                        1

         42                                 58
     0         1                        0             1

               19                                         29
00         0           1           10             0            1

                           8                                       15
         010           0       1            110                0        1


                   0110        0111                        1110         1111

5        29        7       8       14         23               3        11
哈夫曼树的存储结
     构
 用一个大小为 2n- 1 的向量来存储哈夫曼
 树中
的结点,其存储结构为:
 typedef struct { // 结点类型
        int weight ; // 权值,不妨设权值
  均大于零
        int   lchild , rchild , parent ;
                    // 左右孩子及双亲指针
哈夫曼编码的存储结构
     }HTNode , *HuffmanTree;
HT 数组
求哈夫曼编码过程的实例 : Weight parent                                       lchild rchild
      0       1   2   3     4   5     6      7    1
                                                        5     9
                                                              0    0     0
 W    5 29 7          8 14 23 3 11                2
                                                       29    14
                                                              0    0     0
      0       1   2   3   4     5     6     7     3     7    10
                                                              0    0     0
 cd                   0   1 1         0     0     4     8    10
                                                              0    0     0
                                           ↑      5    14    12
                                                              0    0     0
                                          start   6    23     0
                                                             13    0     0
          HC                                      7     3     9
                                                              0    0     0
          1           0 1       1 0
          2           1 0
                                                  8    11    11
                                                              0    0     0
                                                  9     8     0
                                                             11    1
                                                                   0     7
                                                                         0
          3           1 1       1 0
                                                  10    15   12
                                                              0    3
                                                                   0     4
                                                                         0
          4           1 1       1 1                     19   13
                                                              0    8
                                                                   0     9
                                                                         0
                                                  11
          5           1 1       0                       29    0
                                                             14    0
                                                                   5    10
                                                                         0
                                                  12
          6           0 0                               42   15
                                                              0    6
                                                                   0     0
                                                                        11
          7           0 1       1 1               13
                                                  14    58    0
                                                             15    2
                                                                   0    12
                                                                         0
          8           0 1       0                      100    0    13
                                                                   0    14
                                                                         0
                                                  15
求每个字符的 Huffma n 编码是从叶子到根
逆向处理 , 即从叶子出发 , 沿着双亲线索 , 回
溯到根节点 , 求得各个叶子节点所表示的字符
的编码 .
                   HT(‘5’).parent = ‘8’
     0             HT(‘8’).lchild = ‘5’
                   HT(‘8’).parent = ‘19’
     1             HT(‘19’).rchild = ‘8’
                   HT(‘19’).parent = ‘42’
             1
                   HT(‘42’).rchild = ‘19’
         0         HT(‘42’).parent = ‘100’
                   HT(‘100’).ichild = ‘42’
                   HT(‘100’).parent = 0

                   ‘5’: 0110
求哈夫曼编码的算法 6.12:
void HuffmanCoding(HuffmanTree &HT,
HuffmanCode &HC, int *w,int n){
   if(n<=1) return;
   m=2*n-1;
   HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode));
  for(p=HT+1,i=1;i<=n;++i,++p,++w) *p={*w,0,0,0}
  for(;i<=m;++i,++p) *p={0,0,0,0}
  for(i=n+1 ; i<=m ; i++){
      SelectMin(HT , i-1 , s1 , s2) ;  
      HT[s1].parent=i; HT[s2].parent=i ;
          HTIi].1child=s1 ;
          HT[i].rchild=s2 ;
          HT[i].weight=T[s1].weight+T[s2].weight ;
      } // end for 创建哈夫曼树
// 从叶子到根逆向求每个字符的赫夫曼编码

HC=(Huffmancode)malloc((n+1)*sizeof(char *));
cd=(char *)malloc(n*sizeof(char *));
cd[n-1]=“0” ; //c d 临时存储每个叶子节点的哈夫曼
 编码
 for(i=1;i<=n;i++){
 ... // 对每个叶子节点逆向求其 Haffman 编码
 }
   free(cd);
}//Huffmancoding
// 从叶子到根逆向求每个字符的赫夫曼编码
  for(i=1;i<=n;i++){
       start=n-1 ;
                    for( c=i,f=HT[i].parent; f!=0;
c=f,f=HT[f].parent)
        //i 为当前的树叶 , f 为 i 的双亲 . 每次循环沿
着双亲信息逆向搜寻 , 直至根节点

     HC[i]=(char * )malloc((n-start)*sizeof(char));
                    if(HT[f].lchild==c cd[--start]=“0”;
      strcpy(Hc[i] , &cd[start]) ;
       else cd[--start]=“1”;
}
求每个字符的 Huffma n 编码是从叶子到根
逆向处理 , 也可以从根出发 , 遍历整棵树 , 求得
各个叶子节点所表示的字符的编码 .
                    HT(‘100’).lchild =’42’
                    Cd[0] = “0”
      0             HT(‘42’).lchild =’23’
                    Cd[1] = “0”
  0                 HT(‘23’).lchild =0
                    HT(‘23’).rchild =0

                    ‘23’: 00
// 无栈非递归遍历 Haffman 树 , 求 Haffman 编码
...
HC=(HuffmanCode)malloc(n+1)*sizeof(char *));
p = m; cdlen = 0; // 指向根节点
for (i = 1; i<=m; ++i)
      HT[i].weight = 0; // 遍历时用作节点的状态标
    志
while(p) {
... // 从根开始遍历整棵树 , 求取每个节点的编码
}
// 无栈非递归遍历 Haffman 树 , 求 Haffman 编码
 if (HT[p].weight == 0) { // 向左
     HT[p].weight = 1;
     if (HT[p].lchild != 0 )
     { p = HT[p].lchild; cd[cdlen++] = “0”;}
     else if (HT[p].rchild ==0 ) { // 表明该节点为叶子
   , 记录编码
         HC [ p ] = ( c ha r
     * ) ma llo c ( ( c d le n+1) * s iz e o f( c ha r) ) ;
        c d [ c d le n] = “  0” ;
        s trc p y( HC [ p ] , c d ) ;
        } //end else if
 }
// 无栈非递归遍历 Haffman 树 , 求 Haffman 编码
 else if (HT[p].weight ==1 ) { // 向右
   HT[p].weight = 2;
   if(HT[p].rchild != 0){ p = HT[p].rchild; cd[cdlen++]=“1”;}
 else {
      HT[p].weight = 0;
      p = HT[p].parent;
      --cdlen; // 退到父亲节点 , 编码长度减 1
 } //end else
// HT[p].weight = 2 时 ,
     HT[p].weight = 0;              HT(‘23’).lchild =0
     p = HT[p].parent;              HT(‘23’).rchild =0
     --cdlen; // 退到父亲节点 , 编码长度减 1
                                    cd: 00
         0                          p = HT[’23’].parent =
                                    ’42’

 0                                  cdlen = 2-1 = 2
                                    cd: 0
                                    再开始遍历 ’ 42’ 的
                                    右边
                                    ...
上机实习 2-1

More Related Content

Viewers also liked

разжигание рассизма.-предательство_психиатрии-гражданская_комиссия_по_правам...
 разжигание рассизма.-предательство_психиатрии-гражданская_комиссия_по_правам... разжигание рассизма.-предательство_психиатрии-гражданская_комиссия_по_правам...
разжигание рассизма.-предательство_психиатрии-гражданская_комиссия_по_правам...sseleman
 
Наши услуги. Сообщество внутренних коммуникаторов
Наши услуги. Сообщество внутренних коммуникаторовНаши услуги. Сообщество внутренних коммуникаторов
Наши услуги. Сообщество внутренних коммуникаторовAnna Nesmeeva
 
Phanmemdangtinraovatchuykhong
PhanmemdangtinraovatchuykhongPhanmemdangtinraovatchuykhong
Phanmemdangtinraovatchuykhonglanchi1323
 
Słówko angielskiepolski odpowiednik
Słówko angielskiepolski odpowiednikSłówko angielskiepolski odpowiednik
Słówko angielskiepolski odpowiednikmarianowak22
 
(ล่าสุดฉบับแก้ไขครั้งที่ 2) ละหมาดตะรอวีห์ โดย อาริฟีน แสงวิมาน
(ล่าสุดฉบับแก้ไขครั้งที่ 2) ละหมาดตะรอวีห์ โดย อาริฟีน แสงวิมาน(ล่าสุดฉบับแก้ไขครั้งที่ 2) ละหมาดตะรอวีห์ โดย อาริฟีน แสงวิมาน
(ล่าสุดฉบับแก้ไขครั้งที่ 2) ละหมาดตะรอวีห์ โดย อาริฟีน แสงวิมานsunnahstudent
 
Gestion multimedia
Gestion multimediaGestion multimedia
Gestion multimediaVIGOTSKY
 
Qcvn 01 78
Qcvn 01 78Qcvn 01 78
Qcvn 01 78Buu Dang
 
2014 06-22 - mortágua como região de portugal a visitar sara e mariana 8ºe re...
2014 06-22 - mortágua como região de portugal a visitar sara e mariana 8ºe re...2014 06-22 - mortágua como região de portugal a visitar sara e mariana 8ºe re...
2014 06-22 - mortágua como região de portugal a visitar sara e mariana 8ºe re...O Ciclista
 
C4 web
C4 webC4 web
C4 webMami f
 
Institucion educativa la gabriela
Institucion educativa la gabrielaInstitucion educativa la gabriela
Institucion educativa la gabrielaarboledamesa
 

Viewers also liked (18)

Character
CharacterCharacter
Character
 
Diapositivas TIC
Diapositivas TICDiapositivas TIC
Diapositivas TIC
 
разжигание рассизма.-предательство_психиатрии-гражданская_комиссия_по_правам...
 разжигание рассизма.-предательство_психиатрии-гражданская_комиссия_по_правам... разжигание рассизма.-предательство_психиатрии-гражданская_комиссия_по_правам...
разжигание рассизма.-предательство_психиатрии-гражданская_комиссия_по_правам...
 
Nadir
NadirNadir
Nadir
 
1109
11091109
1109
 
Presentatie wordpress veiligheid
Presentatie wordpress veiligheidPresentatie wordpress veiligheid
Presentatie wordpress veiligheid
 
Наши услуги. Сообщество внутренних коммуникаторов
Наши услуги. Сообщество внутренних коммуникаторовНаши услуги. Сообщество внутренних коммуникаторов
Наши услуги. Сообщество внутренних коммуникаторов
 
Phanmemdangtinraovatchuykhong
PhanmemdangtinraovatchuykhongPhanmemdangtinraovatchuykhong
Phanmemdangtinraovatchuykhong
 
Słówko angielskiepolski odpowiednik
Słówko angielskiepolski odpowiednikSłówko angielskiepolski odpowiednik
Słówko angielskiepolski odpowiednik
 
Conceitos de confiabilidade
Conceitos de confiabilidadeConceitos de confiabilidade
Conceitos de confiabilidade
 
Afstuderen Berber
Afstuderen BerberAfstuderen Berber
Afstuderen Berber
 
(ล่าสุดฉบับแก้ไขครั้งที่ 2) ละหมาดตะรอวีห์ โดย อาริฟีน แสงวิมาน
(ล่าสุดฉบับแก้ไขครั้งที่ 2) ละหมาดตะรอวีห์ โดย อาริฟีน แสงวิมาน(ล่าสุดฉบับแก้ไขครั้งที่ 2) ละหมาดตะรอวีห์ โดย อาริฟีน แสงวิมาน
(ล่าสุดฉบับแก้ไขครั้งที่ 2) ละหมาดตะรอวีห์ โดย อาริฟีน แสงวิมาน
 
Gestion multimedia
Gestion multimediaGestion multimedia
Gestion multimedia
 
Qcvn 01 78
Qcvn 01 78Qcvn 01 78
Qcvn 01 78
 
2014 06-22 - mortágua como região de portugal a visitar sara e mariana 8ºe re...
2014 06-22 - mortágua como região de portugal a visitar sara e mariana 8ºe re...2014 06-22 - mortágua como região de portugal a visitar sara e mariana 8ºe re...
2014 06-22 - mortágua como região de portugal a visitar sara e mariana 8ºe re...
 
26 ldz
26 ldz26 ldz
26 ldz
 
C4 web
C4 webC4 web
C4 web
 
Institucion educativa la gabriela
Institucion educativa la gabrielaInstitucion educativa la gabriela
Institucion educativa la gabriela
 

More from Wang Yizhe

第九章+查找[4]
第九章+查找[4]第九章+查找[4]
第九章+查找[4]Wang Yizhe
 
第九章 查找[3]
第九章 查找[3]第九章 查找[3]
第九章 查找[3]Wang Yizhe
 
第九章 查找[2]
第九章 查找[2]第九章 查找[2]
第九章 查找[2]Wang Yizhe
 
第九章 查找[1]
第九章 查找[1]第九章 查找[1]
第九章 查找[1]Wang Yizhe
 
第三章 栈和队列
第三章 栈和队列第三章 栈和队列
第三章 栈和队列Wang Yizhe
 
第七章 图[4]1
第七章 图[4]1第七章 图[4]1
第七章 图[4]1Wang Yizhe
 
第七章 图[3]
第七章 图[3]第七章 图[3]
第七章 图[3]Wang Yizhe
 
第七章 图[2]1
第七章 图[2]1第七章 图[2]1
第七章 图[2]1Wang Yizhe
 
第七章 图[1]
第七章 图[1]第七章 图[1]
第七章 图[1]Wang Yizhe
 
数据结构 总结与复习
数据结构 总结与复习数据结构 总结与复习
数据结构 总结与复习Wang Yizhe
 
第四章 串操作应用举例
第四章 串操作应用举例第四章 串操作应用举例
第四章 串操作应用举例Wang Yizhe
 
第二章 线性表
第二章 线性表第二章 线性表
第二章 线性表Wang Yizhe
 

More from Wang Yizhe (14)

第四章 串
第四章 串第四章 串
第四章 串
 
第六章1
第六章1第六章1
第六章1
 
第九章+查找[4]
第九章+查找[4]第九章+查找[4]
第九章+查找[4]
 
第九章 查找[3]
第九章 查找[3]第九章 查找[3]
第九章 查找[3]
 
第九章 查找[2]
第九章 查找[2]第九章 查找[2]
第九章 查找[2]
 
第九章 查找[1]
第九章 查找[1]第九章 查找[1]
第九章 查找[1]
 
第三章 栈和队列
第三章 栈和队列第三章 栈和队列
第三章 栈和队列
 
第七章 图[4]1
第七章 图[4]1第七章 图[4]1
第七章 图[4]1
 
第七章 图[3]
第七章 图[3]第七章 图[3]
第七章 图[3]
 
第七章 图[2]1
第七章 图[2]1第七章 图[2]1
第七章 图[2]1
 
第七章 图[1]
第七章 图[1]第七章 图[1]
第七章 图[1]
 
数据结构 总结与复习
数据结构 总结与复习数据结构 总结与复习
数据结构 总结与复习
 
第四章 串操作应用举例
第四章 串操作应用举例第四章 串操作应用举例
第四章 串操作应用举例
 
第二章 线性表
第二章 线性表第二章 线性表
第二章 线性表
 

Recently uploaded

SymPy 在微積分上的應用_5.pptx SymPy 在微積分上的應用_5.pptx
SymPy 在微積分上的應用_5.pptx SymPy 在微積分上的應用_5.pptxSymPy 在微積分上的應用_5.pptx SymPy 在微積分上的應用_5.pptx
SymPy 在微積分上的應用_5.pptx SymPy 在微積分上的應用_5.pptxNCU MCL
 
20211119 - demystified artificial intelligence with NLP
20211119 - demystified artificial intelligence with NLP20211119 - demystified artificial intelligence with NLP
20211119 - demystified artificial intelligence with NLPJamie (Taka) Wang
 
买假和真英国驾驶执照买了假的英国驾照,那跟真的有什么区别吗?买假和真正的澳大利亚驾驶执照【微信qoqoqdqd】
买假和真英国驾驶执照买了假的英国驾照,那跟真的有什么区别吗?买假和真正的澳大利亚驾驶执照【微信qoqoqdqd】买假和真英国驾驶执照买了假的英国驾照,那跟真的有什么区别吗?买假和真正的澳大利亚驾驶执照【微信qoqoqdqd】
买假和真英国驾驶执照买了假的英国驾照,那跟真的有什么区别吗?买假和真正的澳大利亚驾驶执照【微信qoqoqdqd】黑客 接单【TG/微信qoqoqdqd】
 
函數畫圖_習題5.pptx 函數畫圖_習題5.pptx 函數畫圖_習題5.pptx
函數畫圖_習題5.pptx 函數畫圖_習題5.pptx 函數畫圖_習題5.pptx函數畫圖_習題5.pptx 函數畫圖_習題5.pptx 函數畫圖_習題5.pptx
函數畫圖_習題5.pptx 函數畫圖_習題5.pptx 函數畫圖_習題5.pptxNCU MCL
 
函數微分_習題4.pptx 函數微分_習題4.pptx 函數微分_習題4.pptx
函數微分_習題4.pptx 函數微分_習題4.pptx 函數微分_習題4.pptx函數微分_習題4.pptx 函數微分_習題4.pptx 函數微分_習題4.pptx
函數微分_習題4.pptx 函數微分_習題4.pptx 函數微分_習題4.pptxNCU MCL
 
20161220 - domain-driven design
20161220 - domain-driven design20161220 - domain-driven design
20161220 - domain-driven designJamie (Taka) Wang
 
函數畫圖_習題6.pptx 函數畫圖_習題6.pptx 函數畫圖_習題6.pptx
函數畫圖_習題6.pptx 函數畫圖_習題6.pptx 函數畫圖_習題6.pptx函數畫圖_習題6.pptx 函數畫圖_習題6.pptx 函數畫圖_習題6.pptx
函數畫圖_習題6.pptx 函數畫圖_習題6.pptx 函數畫圖_習題6.pptxNCU MCL
 
20170104 - transaction_pattern
20170104 - transaction_pattern20170104 - transaction_pattern
20170104 - transaction_patternJamie (Taka) Wang
 
SymPy 在微積分上的應用_4.pptx SymPy 在微積分上的應用_4.pptx
SymPy 在微積分上的應用_4.pptx SymPy 在微積分上的應用_4.pptxSymPy 在微積分上的應用_4.pptx SymPy 在微積分上的應用_4.pptx
SymPy 在微積分上的應用_4.pptx SymPy 在微積分上的應用_4.pptxNCU MCL
 
函數畫圖_習題7.pptx 函數畫圖_習題7.pptx 函數畫圖_習題7.pptx
函數畫圖_習題7.pptx 函數畫圖_習題7.pptx 函數畫圖_習題7.pptx函數畫圖_習題7.pptx 函數畫圖_習題7.pptx 函數畫圖_習題7.pptx
函數畫圖_習題7.pptx 函數畫圖_習題7.pptx 函數畫圖_習題7.pptxNCU MCL
 

Recently uploaded (15)

SymPy 在微積分上的應用_5.pptx SymPy 在微積分上的應用_5.pptx
SymPy 在微積分上的應用_5.pptx SymPy 在微積分上的應用_5.pptxSymPy 在微積分上的應用_5.pptx SymPy 在微積分上的應用_5.pptx
SymPy 在微積分上的應用_5.pptx SymPy 在微積分上的應用_5.pptx
 
20211119 - demystified artificial intelligence with NLP
20211119 - demystified artificial intelligence with NLP20211119 - demystified artificial intelligence with NLP
20211119 - demystified artificial intelligence with NLP
 
买假和真英国驾驶执照买了假的英国驾照,那跟真的有什么区别吗?买假和真正的澳大利亚驾驶执照【微信qoqoqdqd】
买假和真英国驾驶执照买了假的英国驾照,那跟真的有什么区别吗?买假和真正的澳大利亚驾驶执照【微信qoqoqdqd】买假和真英国驾驶执照买了假的英国驾照,那跟真的有什么区别吗?买假和真正的澳大利亚驾驶执照【微信qoqoqdqd】
买假和真英国驾驶执照买了假的英国驾照,那跟真的有什么区别吗?买假和真正的澳大利亚驾驶执照【微信qoqoqdqd】
 
20200323 - AI Intro
20200323 - AI Intro20200323 - AI Intro
20200323 - AI Intro
 
20200226 - AI Overview
20200226 - AI Overview20200226 - AI Overview
20200226 - AI Overview
 
函數畫圖_習題5.pptx 函數畫圖_習題5.pptx 函數畫圖_習題5.pptx
函數畫圖_習題5.pptx 函數畫圖_習題5.pptx 函數畫圖_習題5.pptx函數畫圖_習題5.pptx 函數畫圖_習題5.pptx 函數畫圖_習題5.pptx
函數畫圖_習題5.pptx 函數畫圖_習題5.pptx 函數畫圖_習題5.pptx
 
函數微分_習題4.pptx 函數微分_習題4.pptx 函數微分_習題4.pptx
函數微分_習題4.pptx 函數微分_習題4.pptx 函數微分_習題4.pptx函數微分_習題4.pptx 函數微分_習題4.pptx 函數微分_習題4.pptx
函數微分_習題4.pptx 函數微分_習題4.pptx 函數微分_習題4.pptx
 
20161220 - domain-driven design
20161220 - domain-driven design20161220 - domain-driven design
20161220 - domain-driven design
 
函數畫圖_習題6.pptx 函數畫圖_習題6.pptx 函數畫圖_習題6.pptx
函數畫圖_習題6.pptx 函數畫圖_習題6.pptx 函數畫圖_習題6.pptx函數畫圖_習題6.pptx 函數畫圖_習題6.pptx 函數畫圖_習題6.pptx
函數畫圖_習題6.pptx 函數畫圖_習題6.pptx 函數畫圖_習題6.pptx
 
20170104 - transaction_pattern
20170104 - transaction_pattern20170104 - transaction_pattern
20170104 - transaction_pattern
 
20151111 - IoT Sync Up
20151111 - IoT Sync Up20151111 - IoT Sync Up
20151111 - IoT Sync Up
 
Entities in DCPS (DDS)
Entities in DCPS (DDS)Entities in DCPS (DDS)
Entities in DCPS (DDS)
 
SymPy 在微積分上的應用_4.pptx SymPy 在微積分上的應用_4.pptx
SymPy 在微積分上的應用_4.pptx SymPy 在微積分上的應用_4.pptxSymPy 在微積分上的應用_4.pptx SymPy 在微積分上的應用_4.pptx
SymPy 在微積分上的應用_4.pptx SymPy 在微積分上的應用_4.pptx
 
函數畫圖_習題7.pptx 函數畫圖_習題7.pptx 函數畫圖_習題7.pptx
函數畫圖_習題7.pptx 函數畫圖_習題7.pptx 函數畫圖_習題7.pptx函數畫圖_習題7.pptx 函數畫圖_習題7.pptx 函數畫圖_習題7.pptx
函數畫圖_習題7.pptx 函數畫圖_習題7.pptx 函數畫圖_習題7.pptx
 
20161027 - edge part2
20161027 - edge part220161027 - edge part2
20161027 - edge part2
 

第六章 树和二叉树2

  • 1. 6.8 哈 夫 曼 树 与 哈 夫 曼 编 码 • 最优树 ( 哈夫曼树 ) 的定 义 • 如何构造最优树 • 前缀编码 • 哈夫曼编码
  • 2. 一、最优树的定义 结点的路径长度定义为: 从根结点到该结点的路径上 分支的数目。 树的路径长度定义为: 树中每个结点的路径长度之和。 结点的带权路径长度定义为: 从根结点到该结点的路径长度与 结点上权的乘积。
  • 3. 树的带权路径长度定义为: 树中所有叶子结点的带权路径长度之和 WPL(T) = Σwklk ( 对所有叶子结点 ) 。 例如: 在所有含 n 个叶子结点、并带相同权 值的 m 叉树中,必存在一棵其带权路径 长度取最小值 的树,称为“ 最优树”。
  • 4. WPL(T)= WPL(T)= WPL(T)= 7×2+5×2+ 7×3+5×3+ 7×1+5×2+ 2×2+4×2 4×2+2×1 2×3+4×3 =36 =46 =35
  • 5. 二、如何构造最优树 ( 哈夫曼算法 ) 以二叉树为例: (1) 根据给定的 n 个权值 {w1, w2, …, wn} ,构造 n 棵二叉树的集合 F = {T1, T2, … , Tn} , 其中每棵二叉树 Ti 中均只含一个带 权值 为 wi 的根结点,其左、右子树为空
  • 6. (2)在 F 中选取其根结点的权值为最 小的两棵二叉树,分别作为左、 右子树构造一棵新的二叉树,并 置这棵新的二叉树根结点的权值 为其左、右子树根结点的权值之 和;
  • 7. (3) 从 F 中删去这两棵树,同时加入 刚生成的新树; (4) 重复 (2) 和 (3) 两步,直至 F 中只 含一棵树为止。这棵树便是哈夫
  • 8. 例如 : 已知权值 W={ 5, 6, 2, 9, 7 } 5 6 2 9 7 6 9 7 7 5 2 9 7 13 5 2 6 7
  • 9. 9 7 13 5 2 6 7 29 13 16 6 7 9 7 5 2
  • 10. 注意 : •    ① 初始森林中的 n 棵二叉树, 每棵树有一个孤立的结点,它们既 是根,又是叶子     ② n 个叶子的哈夫曼树要经过 n- 1 次合并,产生 n- 1 个新结点。 最终求得的哈夫曼树中共有 2n- 1 个结点。     ③ 哈夫曼树是严格的二叉树,
  • 11. 前缀编码 在电文传输中,需要将电文中出现的 每个字符进行二进制编码。在设计编码时 需要遵守两个原则: ( 1 )发送方传输的二进制编码,到接收方 解码后必须具有唯一性,即解码结果与发 送方发送的电文完全一样; ( 2 )发送的二进制编码尽可能地短。下面 我们介绍两种编码的方式。
  • 12. 1. 等长编码 这种编码方式的特点 : 每个字符的编码长度相同。 设字符集只含有 4 个字符 A,B,C ,D, 用两位二进制表示的编码分别为 00 , 01 , 10 , 11 。若现在电文为: A B A C C D A , 则应发送二进制序列: 00010010101100 , 总长度为 14 位。当接收方接收到这段电 文后, 将按两位一段进行译码。
  • 13. 2. 不等长编码 在传送电文时,为了使其二 进制位数尽 可能地少,可以将每个字符的编码设计为不等 长 的,使用频度较高的字符分配一个相对比较短 的 编码,使用频度较低的字符分配一个比较长的 编 码。例如,可以为 A , B , C , D 四个字符 分别分配 0 , 00 , 1 , 01 ,并可将上述电文用二进制 序列:
  • 15. 哈夫曼编码的构造方法 : ( 1 )利用字符集中每个字符的使 用 频率作为权值构造一个哈夫曼树; ( 2 )从根结点开始,为到每个叶 子 结点路径上的左分支赋予 0 ,右分 支
  • 16. 例如: 假设有一个电文字符集中有 8 个字符,每 个字符 的使用频率分别为 {0.05,0.29,0.07,0.08,0.14,0.23, 0.03,0.11} ,现以此为例设计哈夫曼编码。 为方便计算,将所有字符的频度乘以 100 ,使 其转换成整型数值集合,得到 { 5, 29, 7, 8, 14, 23,
  • 17. 100 0 1 42 58 0 1 0 1 19 29 00 0 1 10 0 1 8 15 010 0 1 110 0 1 0110 0111 1110 1111 5 29 7 8 14 23 3 11
  • 18. 哈夫曼树的存储结 构 用一个大小为 2n- 1 的向量来存储哈夫曼 树中 的结点,其存储结构为: typedef struct { // 结点类型       int weight ; // 权值,不妨设权值 均大于零       int lchild , rchild , parent ; // 左右孩子及双亲指针 哈夫曼编码的存储结构     }HTNode , *HuffmanTree;
  • 19. HT 数组 求哈夫曼编码过程的实例 : Weight parent lchild rchild 0 1 2 3 4 5 6 7 1 5 9 0 0 0 W 5 29 7 8 14 23 3 11 2 29 14 0 0 0 0 1 2 3 4 5 6 7 3 7 10 0 0 0 cd 0 1 1 0 0 4 8 10 0 0 0 ↑ 5 14 12 0 0 0 start 6 23 0 13 0 0 HC 7 3 9 0 0 0 1 0 1 1 0 2 1 0 8 11 11 0 0 0 9 8 0 11 1 0 7 0 3 1 1 1 0 10 15 12 0 3 0 4 0 4 1 1 1 1 19 13 0 8 0 9 0 11 5 1 1 0 29 0 14 0 5 10 0 12 6 0 0 42 15 0 6 0 0 11 7 0 1 1 1 13 14 58 0 15 2 0 12 0 8 0 1 0 100 0 13 0 14 0 15
  • 20. 求每个字符的 Huffma n 编码是从叶子到根 逆向处理 , 即从叶子出发 , 沿着双亲线索 , 回 溯到根节点 , 求得各个叶子节点所表示的字符 的编码 . HT(‘5’).parent = ‘8’ 0 HT(‘8’).lchild = ‘5’ HT(‘8’).parent = ‘19’ 1 HT(‘19’).rchild = ‘8’ HT(‘19’).parent = ‘42’ 1 HT(‘42’).rchild = ‘19’ 0 HT(‘42’).parent = ‘100’ HT(‘100’).ichild = ‘42’ HT(‘100’).parent = 0 ‘5’: 0110
  • 21. 求哈夫曼编码的算法 6.12: void HuffmanCoding(HuffmanTree &HT, HuffmanCode &HC, int *w,int n){ if(n<=1) return; m=2*n-1; HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode)); for(p=HT+1,i=1;i<=n;++i,++p,++w) *p={*w,0,0,0} for(;i<=m;++i,++p) *p={0,0,0,0} for(i=n+1 ; i<=m ; i++){ SelectMin(HT , i-1 , s1 , s2) ;   HT[s1].parent=i; HT[s2].parent=i ;           HTIi].1child=s1 ;           HT[i].rchild=s2 ;           HT[i].weight=T[s1].weight+T[s2].weight ; } // end for 创建哈夫曼树
  • 22. // 从叶子到根逆向求每个字符的赫夫曼编码 HC=(Huffmancode)malloc((n+1)*sizeof(char *)); cd=(char *)malloc(n*sizeof(char *)); cd[n-1]=“0” ; //c d 临时存储每个叶子节点的哈夫曼 编码 for(i=1;i<=n;i++){ ... // 对每个叶子节点逆向求其 Haffman 编码 } free(cd); }//Huffmancoding
  • 23. // 从叶子到根逆向求每个字符的赫夫曼编码 for(i=1;i<=n;i++){ start=n-1 ;          for( c=i,f=HT[i].parent; f!=0; c=f,f=HT[f].parent) //i 为当前的树叶 , f 为 i 的双亲 . 每次循环沿 着双亲信息逆向搜寻 , 直至根节点 HC[i]=(char * )malloc((n-start)*sizeof(char));         if(HT[f].lchild==c cd[--start]=“0”; strcpy(Hc[i] , &cd[start]) ; else cd[--start]=“1”; }
  • 24. 求每个字符的 Huffma n 编码是从叶子到根 逆向处理 , 也可以从根出发 , 遍历整棵树 , 求得 各个叶子节点所表示的字符的编码 . HT(‘100’).lchild =’42’ Cd[0] = “0” 0 HT(‘42’).lchild =’23’ Cd[1] = “0” 0 HT(‘23’).lchild =0 HT(‘23’).rchild =0 ‘23’: 00
  • 25. // 无栈非递归遍历 Haffman 树 , 求 Haffman 编码 ... HC=(HuffmanCode)malloc(n+1)*sizeof(char *)); p = m; cdlen = 0; // 指向根节点 for (i = 1; i<=m; ++i) HT[i].weight = 0; // 遍历时用作节点的状态标 志 while(p) { ... // 从根开始遍历整棵树 , 求取每个节点的编码 }
  • 26. // 无栈非递归遍历 Haffman 树 , 求 Haffman 编码 if (HT[p].weight == 0) { // 向左 HT[p].weight = 1; if (HT[p].lchild != 0 ) { p = HT[p].lchild; cd[cdlen++] = “0”;} else if (HT[p].rchild ==0 ) { // 表明该节点为叶子 , 记录编码 HC [ p ] = ( c ha r * ) ma llo c ( ( c d le n+1) * s iz e o f( c ha r) ) ; c d [ c d le n] = “ 0” ; s trc p y( HC [ p ] , c d ) ; } //end else if }
  • 27. // 无栈非递归遍历 Haffman 树 , 求 Haffman 编码 else if (HT[p].weight ==1 ) { // 向右 HT[p].weight = 2; if(HT[p].rchild != 0){ p = HT[p].rchild; cd[cdlen++]=“1”;} else { HT[p].weight = 0; p = HT[p].parent; --cdlen; // 退到父亲节点 , 编码长度减 1 } //end else
  • 28. // HT[p].weight = 2 时 , HT[p].weight = 0; HT(‘23’).lchild =0 p = HT[p].parent; HT(‘23’).rchild =0 --cdlen; // 退到父亲节点 , 编码长度减 1 cd: 00 0 p = HT[’23’].parent = ’42’ 0 cdlen = 2-1 = 2 cd: 0 再开始遍历 ’ 42’ 的 右边 ...