哈夫曼树的基本概念:

在了解哈夫曼树的概念之前,我们要了解到的是带权路径长度的概念:

  1. 在实际应用当中,树中的结点往往都会被赋予某种意义的数值,这个数值就称为该结点的权;
  2. 从根结点到任意结点的路径长度(经过的边数)与该结点上的权值得乘积称之为该结点的带权路径长度;
  3. 树中所有叶结点的带权路径长度称为该树的带权路径长度(WPL),其计算公式如下:

那么可以想象,给定n(n>1)个结点,并给定每个结点的权值,构造出来的树是有许多中的,每种树的WPL也可能不同,那么在这些构造出来的树当中,WPL最小的那颗树就称之为哈夫曼树,也称之为最优二叉树。

哈夫曼树的应用:

由哈夫曼树的特性,衍生出来的应用场景是非常多的,其中应用最多的就是压缩编码。

哈夫曼树的构造:

哈夫曼树的构造的基本思想其实就是,在给定的n个结点序列中,每次选取两个权值最小的两个结点凑成一颗二叉树,这两个结点的权值之和就是它们的新根结点,将这个新的新结点从新放回序列中,循环上述操作,直至最终所有的结点序列构建成一颗二叉树,也就是最终的哈夫曼树。

以序列{a(45),b(13),c(12),d(16),e(9),f(5)}为例,建立哈夫曼树的步骤如下所示:

哈夫曼树构造过程:

运用不同的存储方式和结点定义方式,代码有些许不同,但是整体的编码思想就是上述过程的衍生,本文以最简单的顺序存储来实现哈夫曼树的构造:

1.结点定义:

由哈夫曼树的性质其实可以推出哈夫曼树结点所具备的基本要素:

包括了元素,父节点,左孩子结点,右孩子结点,权值。

那么定义如下:

typedef struct {char data; //元素int weight; //权值int parent, lch,rch; //父节点,左孩子,右孩子
}HTNode,*HuffmanTree;

2.构造哈夫曼树:

void CreateHuffmanTree(HuffmanTree& HT, int n)
{if (n <= 1)  cout << "error" << endl;int s1, s2;int m = n * 2 - 1;  // 没有度为1的节点,则总结点是2*叶子节点数-1个 HT = new HTNode[m + 1];for (int i = 1; i <= m; ++i)  // 初始化 {HT[i].data = '*';  //所有结点元素值设为‘*’,根据自己的需要可以更改或者删除这行代码HT[i].parent = 0; HT[i].lch = 0;HT[i].rch = 0;}for (int i = 1; i <= n; ++i){cin >> HT[i].data >> HT[i].weight; //从键盘输入结点元素值和权值}for (int i = n + 1; i <= m; ++i){select(HT, i - 1, s1, s2);  // 从前面的范围里选择权重最小的两个节点 HT[s1].parent = i;  HT[s2].parent = i;HT[i].lch = s1;HT[i].rch = s2;HT[i].weight = HT[s1].weight + HT[s2].weight;  // 得到一个新节点 }
}

3.选择最小两个结点:

void select(HuffmanTree HT, int top, int  &s1, int &s2)
{int min = INT_MAX;for (int i = 1; i <= top; ++i)  // 选择没有双亲的节点中,权重最小的节点 {if (HT[i].weight < min && HT[i].parent == 0){min = HT[i].weight;s1 = i;}}min = INT_MAX;for (int i = 1; i <= top; ++i)  // 选择没有双亲的节点中,权重次小的节点 {if (HT[i].weight < min && i != s1 && HT[i].parent == 0){min = HT[i].weight;s2 = i;}}
}

完整代码:

#include<iostream>
using namespace std;
typedef struct {char data;int weight;int parent, lch,rch;
}HTNode,*HuffmanTree;
void select(HuffmanTree HT, int top, int  &s1, int &s2)
{int min = INT_MAX;for (int i = 1; i <= top; ++i)  // 选择没有双亲的节点中,权重最小的节点 {if (HT[i].weight < min && HT[i].parent == 0){min = HT[i].weight;s1 = i;}}min = INT_MAX;for (int i = 1; i <= top; ++i)  // 选择没有双亲的节点中,权重次小的节点 {if (HT[i].weight < min && i != s1 && HT[i].parent == 0){min = HT[i].weight;s2 = i;}}
}void CreateHuffmanTree(HuffmanTree& HT, int n)
{if (n <= 1)  cout << "error" << endl;int s1, s2;int m = n * 2 - 1;  // 没有度为1的节点,则总结点是2*叶子节点数-1个 HT = new HTNode[m + 1];for (int i = 1; i <= m; ++i)  // 初始化 {HT[i].data = '*';HT[i].parent = 0;HT[i].lch = 0;HT[i].rch = 0;}for (int i = 1; i <= n; ++i){cin >> HT[i].data >> HT[i].weight;}for (int i = n + 1; i <= m; ++i){select(HT, i - 1, s1, s2);  // 从前面的范围里选择权重最小的两个节点 HT[s1].parent = i;HT[s2].parent = i;HT[i].lch = s1;HT[i].rch = s2;HT[i].weight = HT[s1].weight + HT[s2].weight;  // 得到一个新节点 }
}
int main() {HuffmanTree hf;CreateHuffmanTree(hf, 5);for (int i = 1; i <= 9; i++){cout<< i <<": " << hf[i].data << " " << hf[i].weight << " "<<hf[i].parent<<" " << hf[i].lch << " " << hf[i].rch << endl;}return 0;
}

执行结果:

哈夫曼树的基本概念及其构建(C++)相关推荐

  1. 三十、赫夫曼树的设计与代码实现

    一.基本介绍 给定 n 个权值作为 n 个叶子结点,构造一棵二叉树,若该树的带权路径长度(wpl)达到最小,称这样的二叉树为 最优二叉树,也称为哈夫曼树(Huffman Tree), 还有的书翻译为霍 ...

  2. 赫夫曼树建立c语言源程序编译结果详细解释,c语言构建哈夫曼树(附运行结果图)[本站推荐]...

    #include#include#include int m,s1,s2; typedef struct { unsigned int weight; unsigned int parent,lchi ...

  3. 哈夫曼树【最优二叉树】【Huffman】

    [转载]只为让价值共享,如有侵权敬请见谅! 一.哈夫曼树的概念和定义 什么是哈夫曼树? 让我们先举一个例子. 判定树: 在很多问题的处理过程中,需要进行大量的条件判断,这些判断结构的设计直接影响着程序 ...

  4. 【数据结构(25)】5.7 哈夫曼树及其应用

    文章目录 前言 一.哈夫曼树的基本概念 1. 哈夫曼树的特点 二.哈夫曼树的构造算法 1. 哈夫曼树的构造过程 2. 哈夫曼算法的实现 2.1 哈夫曼算法思路 2.2 哈夫曼算法实现 三.哈夫曼编码 ...

  5. 算法与数据结构 --- 哈夫曼树及其应用

    第一部分 --- 哈夫曼树的基本概念 对一个判断树的判断次序进行改变后判断的总次数就可能截然不同 如上图,在面对一万个数据的时候,左边的判断树的判断总次数为22000次,右边的判断树的判断总次数为31 ...

  6. 【数据结构——哈夫曼树及其应用】

    [数据结构--哈夫曼树及其应用] 一.哈夫曼树的基本概念 二.哈夫曼树的构造算法 (一)哈夫曼树的构造过程 (二)哈夫曼树构造算法的实现 1.初始化 2.创建树 3.完整的创建哈夫曼树代码 三.哈夫曼 ...

  7. 数据结构与算法--哈夫曼树及其应用

    一.哈夫曼树的基本概念 1) 路径: 从树中一个结点到另一个结点之间的分支构成这两个结点间的路径 2) 结点的路径长度: 两结点间路径上的分支数           3) 树的路径长度:从树根到每一个 ...

  8. 哈夫曼树及哈夫曼编码(考试常考版)

    哈夫曼树的基本概念 哈夫曼树的定义是对一组具有确定权值的叶子节点,选出最小带权路径长度的二叉树为哈夫曼树(WPL最小),也称最优二叉树 哈夫曼算法的实现 注意:哈夫曼树在构造时选择两个最小的权值点,默 ...

  9. 哈夫曼树+K叉哈夫曼树

    目录 基本概念 构造方法 证明 代码 k叉哈夫曼树 例题 基本概念 问题:给定n个权值,作为n个叶结点,构造一棵二叉树,而这棵树的特点是,有n个叶节点,叶节点的值为给定的权值.而内部节点的值为子树的权 ...

最新文章

  1. 我们眼中的2015年互联网10大产品事件
  2. 我们已经不用 AOP 做日志很久了!
  3. 作为程序员,你吃过哪些数学的亏?
  4. C++回声服务器_4-UDP connect版本客户端
  5. 教你轻松解决苹果Mac安装Axure首次打开报错的问题
  6. matlab vav终端控制器编程,基于TRNSYS与VAV控制系统与仿真.pdf
  7. java幻灯片效果_java实现多种幻灯片切换特效(经典,附源码)
  8. 网络对抗技术 实验一
  9. P6跨级晋升P8再到P10,我的11年成长之路
  10. 展讯7731C_M Android6.0 充电指示灯实现
  11. ImageLoader加载圆形图片
  12. 【Android】带可输入功能的下拉框EditSpinner,附带Filter功能
  13. 数据库触发器(转自http://blog.csdn.net/chinayuan/article/details/6292335/#)
  14. 一行python代码画粑粑_如何阅读《JavaScript高级程序设计》(一)
  15. MATLAB图片导出PDF格式,并且控制图片白色边框大小——非代码方法
  16. 更换电脑开机的音乐和其它音乐
  17. 从“非主流”到“潮流”,开源早已值得拥有
  18. QT+opengl实现3D点云和三维坐标系
  19. 深入Python3阅读day01——从一个Python程序开始
  20. ssm高校学生档案信息管理系统毕业设计源码010936

热门文章

  1. SEPC:商汤提出使用3D卷积从FPN中提取尺度不变特征,涨点神器 | CVPR 2020
  2. R语言ggpubr包的ggscatter函数可视化散点图(scatter plot)、cor.coef为散点图添加相关性系数及其显著性、cor.coeff.args参数指定相关性计算方法及显示格式
  3. 课程设计-基于SSM的美容美发造型预约管理系统代码Java理发剪发设计造型系统vue美发店管理系统
  4. 基于java ssm vue的仓库仓储物流管理系统
  5. 统计学在金融中的应用
  6. java 获取url 号后面,java获取url地址后缀名
  7. 如何把图片转换成word文档?说一个转换途径
  8. 交换机端口聚合(思科模拟器实现)
  9. 较好游戏型计算机配置单,游戏多开型装机 5500元i7-7700配GTX1060游戏电脑配置推荐...
  10. MINIUI的使用以及一些常用小知识(前端)