【数据结构】树:哈夫曼树(Huffman Tree,也称哈弗曼、赫夫曼树)、哈夫曼编码解析与实现(c++)

本文介绍了哈夫曼树(赫夫曼树)的概念,包括路径长度、带权路径长度等,并阐述了哈夫曼树(最优二叉树)的性质。接着详细讲解了如何通过哈夫曼算法构建哈夫曼树,并提供了一个构建过程的示例。此外,文章还讨论了哈夫曼编码,解释了前缀编码的重要性以及如何利用哈夫曼树生成编码,以实现数据压缩。最后,作者分享了自己在大学时期编写的一个哈夫曼编译器的源码和实习报告。
摘要由CSDN通过智能技术生成

#笔记整理

树的定义参照前文:
二叉树、遍历二叉树与线索二叉树等树的定义与解析、二叉树遍历实现



哈夫曼树(也称赫夫曼树)

相关概念:

① 路径长度
从树中一个结点到另一个结点之间的分支(树枝)构成这两个结点之间的路径, 路径上的分支(树枝)数目称做路径长度

② 树的路径长度
从树根到每一结点的路径长度之和(所有结点到根的路径长度的和)。

③ 结点的权和带权路径长度
给树的每个结点赋予一个具有某种实际意义的实数,我们称该实数为这个结点的权。
在树形结构中,我们把从树根某一结点的路径长度与该结点的乘积,叫做该结点的带权路径长度(Weighted Path Length of Tree,WPL)

④ 二叉树的带权路径长度
设二叉树具有n个带权值的叶子结点,那么从根结点到各个叶子结点的路径长度与相应叶子结点权值乘积,叫做二叉树的带权路径长度

哈夫曼树(最优二叉树)

具有最小带权路径长度的二叉树称为哈夫曼树
如下图 ( c )
在这里插入图片描述

构建哈夫曼树(哈夫曼算法)
  1. 由给定的n个权值 W 1 , W 2 , . . . , W n {W1,W2,...,Wn} W1,W2,...,Wn,构造 n 棵只有一个结点的二叉树,从而得到一个二叉树的集合 F = T 1 , T 2 , . . . , T n F={T1,T2,...,Tn} F=T1,T2,...,Tn;
  2. 在F中选取根结点的权值最小和次小的两棵二叉树作为左、右子树构造一棵新的二叉树,这棵新的二叉树根结点的权值为其左、右子树根结点权值之和;
  3. 在集合F中删除作为左、右子树的两棵二叉树,并将新建立的二叉树加入到集合F中;
  4. 重复(2)、(3)两步,当F中只剩下一棵二叉树时,这棵二叉树便是所要建立的赫夫曼树。

示例:
在这里插入图片描述

哈夫曼树中没有度为 1 的结点(可称为严格的(或正则的)二叉树),因此一棵有 n 个叶子节点的哈夫曼树一共有 2n - 1 个结点,可以存储在一个大小为 2n - 1 的一维数组中。

算法实现:

// 创建哈夫曼树 hTree
void createHuffTree(vector<HuffTreeNode> &hTree){
   
    int n, s1, s2, len;
    char c;     // 字符
    int weight; // 字符权值

    cout << "请输入字符集大小(即叶子数):" << endl;
    cin >> n;
    len = 2 * n - 1;  // 哈夫曼树的结点数
    hTree.resize(len);
    cout << n << "个字符及其的权值是:(输入格式如:a1 b5 d23,空格分隔)" << endl;
    for(int i = 0; i < n; i++){
   
        cin >> c >> weight;
        hTree[i].data   = c;
        hTree[i].weight = weight;
        hTree[i].parent = -1;
        hTree[i].
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值