树与二叉树 (2) -- 哈夫曼树

森林、树与二叉树

一、转化思想及遍历

  • 树转化成二叉树

//其根结点的右子树总为空

  1. 在兄弟之间加一连线
  2. 对每个结点,只保留与第一个孩子的连线,去除其他孩子之间的连线
  3. 以树的根节点为轴心,顺时针转 45°
    在这里插入图片描述
  • 森林转换成二叉树

    1. 将森林中每棵树转换成相应二叉树
    2. 将每棵树的根结点用线相连
    3. 以第一棵树根节点为二叉树的根,以其为轴心,顺时针旋转45°

在这里插入图片描述

二、二叉排序树

1. 定义

二叉排序树(二叉查找树)或者是一颗空树,或者是具有下列特性的二叉树。

(1)若左子树非空,则左子树上所有结点的值均小于根结点的值;

(2)若右子树非空,则右子树上所有结点的值均大于根结点的值;

(3)左、右子树也分别是一棵二叉排序树。

根据二叉排序树的定义,左子树结点值 < 根结点值 < 右子树结点值,所以对二叉排序树进
行中序遍历,可以得到一个 递增 的有序序列。

2. 插入操作

  • 若原二叉排序树为空,则直接插入结点;否则,若关键字k小于根结点值,则插入到左子树,若关键字k大于根结点值,则插入到右子树。

​ //则向二叉排序树中插入一个新结点时,新结点一定会成为该树的一个叶子结点

3. 删除操作

(1)若被删除的结点是叶子结点,则直接删除;

(2)若结点只有一棵左子树或者右子树,则让该结点的子树成为其父结点的子树;

(3)若结点有左、右两棵子树,则今该结点的直接后继(直接前驱)代替该结点,然后从二叉排序树中删去这个直接后继(直接前驱),这样就转换成了前两种情况。
在这里插入图片描述

三、 哈夫曼树

1.定义:

树中结点常被赋予一个代表某种意义的数值,那个数值称为该结点的权。

  • 结点的带权路径长度:从树的根到任意结点的路径长度(经过的边数)与该结点上权值的乘积。
  • 树的带权路径长度:树中所有叶结点的带权路径长度之和,记为WPL一三wh.
  • 哈夫曼树:带权路径长度最小的二叉树,也称最优二叉树。

2. 构造算法

// 哈夫曼树结点的定义
struct HuffmanNode { 
     char   character;	         // 待编码的符号
     double  weight;	     // 符号出现的频率
     int  parent, lchild, rchild;  // 父结点、左, 右孩子结点的位置};

class HuffmanTree  { 
     vector<HuffmanNode> hufftree;  // 树中所有结点的存储空间
     int n;			           // 叶子结点数
public:
     HuffmanTree(vector<HuffmanNode> &leafs);
     …
};
     
    

//Huffman树的构造函数
HuffmanTree::HuffmanTree(vector<HuffmanNode> &leafs) { 
     n = leafs.size();	
     hufftree.resize(2*n-1); 
     for(int i=0;  i<n;  i++) {                // 初始化 n 个二叉树 
          hufftree[i].character = leafs[i].character;  
          hufftree[i].weight = leafs[i].weight; 
          hufftree[i].parent = hufftree[i].lchild = hufftree[i].rchild = -1;     } 
    for( i = n;  i < 2*n-1;  i++) { 
         int least, less; 
         SelectSmall(least, less, i);      // 找到最小、次小的根结点下标 
         hufftree[least].parent = hufftree[less].parent = i; 
         hufftree[i].parent = -1; 
         hufftree[i].lchild = least; 
         hufftree[i].rchild = less;
         hufftree[i].weight = hufftree[least].weight + hufftree[less].weight; 
    } 
} 

3. 例题

  • 有一电文使用五种字符 a, b, c, d, e 中,其出现频率依次为4.7.5.2.9。

    (1)试画出对应的哈夫曼树(要求左子树根结点的权小于等于右子树根结点的权)。

    (2)求出每个字符的哈夫曼编码。

    (3)译出编码序列11000111000101011的相应电文。

    (4)求带权路径长度。

解:

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值