哈夫曼树的基本概念及其构建(C++)
哈夫曼树的基本概念:
在了解哈夫曼树的概念之前,我们要了解到的是带权路径长度的概念:
- 在实际应用当中,树中的结点往往都会被赋予某种意义的数值,这个数值就称为该结点的权;
- 从根结点到任意结点的路径长度(经过的边数)与该结点上的权值得乘积称之为该结点的带权路径长度;
- 树中所有叶结点的带权路径长度称为该树的带权路径长度(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++)相关推荐
- 三十、赫夫曼树的设计与代码实现
一.基本介绍 给定 n 个权值作为 n 个叶子结点,构造一棵二叉树,若该树的带权路径长度(wpl)达到最小,称这样的二叉树为 最优二叉树,也称为哈夫曼树(Huffman Tree), 还有的书翻译为霍 ...
- 赫夫曼树建立c语言源程序编译结果详细解释,c语言构建哈夫曼树(附运行结果图)[本站推荐]...
#include#include#include int m,s1,s2; typedef struct { unsigned int weight; unsigned int parent,lchi ...
- 哈夫曼树【最优二叉树】【Huffman】
[转载]只为让价值共享,如有侵权敬请见谅! 一.哈夫曼树的概念和定义 什么是哈夫曼树? 让我们先举一个例子. 判定树: 在很多问题的处理过程中,需要进行大量的条件判断,这些判断结构的设计直接影响着程序 ...
- 【数据结构(25)】5.7 哈夫曼树及其应用
文章目录 前言 一.哈夫曼树的基本概念 1. 哈夫曼树的特点 二.哈夫曼树的构造算法 1. 哈夫曼树的构造过程 2. 哈夫曼算法的实现 2.1 哈夫曼算法思路 2.2 哈夫曼算法实现 三.哈夫曼编码 ...
- 算法与数据结构 --- 哈夫曼树及其应用
第一部分 --- 哈夫曼树的基本概念 对一个判断树的判断次序进行改变后判断的总次数就可能截然不同 如上图,在面对一万个数据的时候,左边的判断树的判断总次数为22000次,右边的判断树的判断总次数为31 ...
- 【数据结构——哈夫曼树及其应用】
[数据结构--哈夫曼树及其应用] 一.哈夫曼树的基本概念 二.哈夫曼树的构造算法 (一)哈夫曼树的构造过程 (二)哈夫曼树构造算法的实现 1.初始化 2.创建树 3.完整的创建哈夫曼树代码 三.哈夫曼 ...
- 数据结构与算法--哈夫曼树及其应用
一.哈夫曼树的基本概念 1) 路径: 从树中一个结点到另一个结点之间的分支构成这两个结点间的路径 2) 结点的路径长度: 两结点间路径上的分支数 3) 树的路径长度:从树根到每一个 ...
- 哈夫曼树及哈夫曼编码(考试常考版)
哈夫曼树的基本概念 哈夫曼树的定义是对一组具有确定权值的叶子节点,选出最小带权路径长度的二叉树为哈夫曼树(WPL最小),也称最优二叉树 哈夫曼算法的实现 注意:哈夫曼树在构造时选择两个最小的权值点,默 ...
- 哈夫曼树+K叉哈夫曼树
目录 基本概念 构造方法 证明 代码 k叉哈夫曼树 例题 基本概念 问题:给定n个权值,作为n个叶结点,构造一棵二叉树,而这棵树的特点是,有n个叶节点,叶节点的值为给定的权值.而内部节点的值为子树的权 ...
最新文章
- 我们眼中的2015年互联网10大产品事件
- 我们已经不用 AOP 做日志很久了!
- 作为程序员,你吃过哪些数学的亏?
- C++回声服务器_4-UDP connect版本客户端
- 教你轻松解决苹果Mac安装Axure首次打开报错的问题
- matlab vav终端控制器编程,基于TRNSYS与VAV控制系统与仿真.pdf
- java幻灯片效果_java实现多种幻灯片切换特效(经典,附源码)
- 网络对抗技术 实验一
- P6跨级晋升P8再到P10,我的11年成长之路
- 展讯7731C_M Android6.0 充电指示灯实现
- ImageLoader加载圆形图片
- 【Android】带可输入功能的下拉框EditSpinner,附带Filter功能
- 数据库触发器(转自http://blog.csdn.net/chinayuan/article/details/6292335/#)
- 一行python代码画粑粑_如何阅读《JavaScript高级程序设计》(一)
- MATLAB图片导出PDF格式,并且控制图片白色边框大小——非代码方法
- 更换电脑开机的音乐和其它音乐
- 从“非主流”到“潮流”,开源早已值得拥有
- QT+opengl实现3D点云和三维坐标系
- 深入Python3阅读day01——从一个Python程序开始
- ssm高校学生档案信息管理系统毕业设计源码010936
热门文章
- SEPC:商汤提出使用3D卷积从FPN中提取尺度不变特征,涨点神器 | CVPR 2020
- R语言ggpubr包的ggscatter函数可视化散点图(scatter plot)、cor.coef为散点图添加相关性系数及其显著性、cor.coeff.args参数指定相关性计算方法及显示格式
- 课程设计-基于SSM的美容美发造型预约管理系统代码Java理发剪发设计造型系统vue美发店管理系统
- 基于java ssm vue的仓库仓储物流管理系统
- 统计学在金融中的应用
- java 获取url 号后面,java获取url地址后缀名
- 如何把图片转换成word文档?说一个转换途径
- 交换机端口聚合(思科模拟器实现)
- 较好游戏型计算机配置单,游戏多开型装机 5500元i7-7700配GTX1060游戏电脑配置推荐...
- MINIUI的使用以及一些常用小知识(前端)