哈夫曼(Huffman)树及其应用
Huffman树又称最优树,是一类带权路径长度最短的树,带权路径长度为从该节点到树根之间的路径长度与节点上权值的成积。
那么如何构建一个Huffman树呢?就需要Huffman算法
1、利用给定的n个权值构成有n个二叉树的集合F,每个二叉树就只有一个带权值的根节点,其左右子树都为空。
2、选取两课根节点权值最小的树作为左右子树,且重置新的二叉树的根节点的权值为左右子树权值之和。
3、在集合F中删掉这两课子树,并将新得到的二叉树加入到F中去。
4、重复2、3操作直至F中只剩下一棵子树。
如下图:Huffman的构造过程(其中红色数字表示的是节点的权值)

Huffman存储:Huffman树中没有度为一的结点,一棵有n个叶子结点的Huffman树共有2n-1个结点,可以存储在一个大小为2n-1的一维数组中。
编码走一条从根路径出发到叶子节点的路径;译码走一条从叶子节点出发到根的路径,对于每个结点而言即需要知道其父亲结点又要知道其左右孩子结点。
Huffman树建立主要代码实现:
:以下代码是借助自己写的堆实现的,也可以用vector容器
void CreateTree(const T* a, size_t size, const T& invalid)
{
assert(a);
Heap<Node*, NodeCompare<T>> minHeap;//一个小堆的结构
for (size_t i = ; i < size; ++i)
{
if (a[i] != invalid)
{
//将a[i]构建成节点,插入堆
Node* node = new Node(a[i]);
minHeap.Push(node);
}
}
while (minHeap.Size()>)
{//得到权值最小的两个元素作为左右子树
Node* left = minHeap.Top();
minHeap.Pop();
Node* right = minHeap.Top();
minHeap.Pop();
//利用左右子树的权值之和构造出结点
Node* parent = new Node(left->_weight + right->_weight);
//进行链接
parent->_left = left;
parent->_right = right;
left->_parent = parent;
right->_parent = parent;
minHeap.Push(parent);
}
_root = minHeap.Top(); }
Huffman编码:约定左分支表示字符'0',右分支表示字符'1',则可以从根节点到叶子节点的路径上分支字符组成的字符串作为该叶子结点字符的编码, 以下写了2 种方法实现记录Huffman编码
1.递归
void _GenerateHuffmanCode(HuffmanTreeNode<FileInfo>* root)//从根节点出发递归生成HuffmanTree编码
{
if (root == NULL)
{
return;
}
_GenerateHuffmanCode(root->_left);
_GenerateHuffmanCode(root->_right);
if (root->_left == NULL && root->_right == NULL)//节点为叶子节点
{
HuffmanTreeNode<FileInfo>* cur = root;
HuffmanTreeNode<FileInfo>* parent = cur->_parent;
string& code = _infos[cur->_weight._ch]._code;//FileInFo即为weight,.ch指的是字符是什么._code表示编码
while (parent)
{
if (parent->_left == cur)
{
code += '';
}
else
{
code += '';
}
cur = parent;
parent = cur->_parent;
}
reverse(code.begin(), code.end());
}
}
文件压缩:
1、打开文件统计字符次数,利用字符次数建立Huffman树。
2、根据Huffman树遍历出Huffman编码。
3、将每一个字符的编码写入压缩文件。
4、将字符总数及每个按文件中出现顺序字符的次数写入配置文件
文件解压缩:
1、读配置文件,将字符写入解压缩文件。
哈夫曼(Huffman)树及其应用的更多相关文章
- [数据结构与算法]哈夫曼(Huffman)树与哈夫曼编码
声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...
- 哈夫曼(Huffman)树+哈夫曼编码
前天acm实验课,老师教了几种排序,抓的一套题上有一个哈夫曼树的题,正好之前离散数学也讲过哈夫曼树,这里我就结合课本,整理一篇关于哈夫曼树的博客. 主要摘自https://www.cnblogs.co ...
- 数据结构实训——哈夫曼(Huffman)编/译码器
题目4.哈夫曼(Huffman)编/译码器(限1人完成) [问题描述] 利用哈夫曼编码进行通信可以大大提高信道利用率,缩短信息传输时间,降低传输成本.但是,这要求在发送端通过一个编码系统对待传数据预先 ...
- 哈夫曼(Huffman)编码
哈夫曼编码(Huffman Coding)是一种非常经典的编码方式,属于可变字长编码(VLC)的一种,通过构造带权路径长度最小的最优二叉树以达到数据压缩的目的.哈弗曼编码实现起来也非常简单,在实际的笔 ...
- 重温经典之赫夫曼(Huffman)编码
先看看赫夫曼树假设有n个权值{w1,w2,…,wn},构造一个有n个叶子结点的二叉树,每个叶子结点权值为wi,则其中带权路径长度WPL最小的二叉树称作赫夫曼树或最优二叉树. 赫夫曼树的构造,赫夫曼最早 ...
- 数据结构-哈夫曼(Huffman)
#include <iostream> #include <cstdio> #include <malloc.h> #define LIST_INIT_SIZE 1 ...
- javascript实现数据结构: 树和二叉树的应用--最优二叉树(赫夫曼树),回溯法与树的遍历--求集合幂集及八皇后问题
赫夫曼树及其应用 赫夫曼(Huffman)树又称最优树,是一类带权路径长度最短的树,有着广泛的应用. 最优二叉树(Huffman树) 1 基本概念 ① 结点路径:从树中一个结点到另一个结点的之间的分支 ...
- HUFFMAN 树
在一般的数据结构的书中,树的那章后面,著者一般都会介绍一下哈夫曼(HUFFMAN) 树和哈夫曼编码.哈夫曼编码是哈夫曼树的一个应用.哈夫曼编码应用广泛,如 JPEG中就应用了哈夫曼编码. 首先介绍什么 ...
- [C++]哈夫曼树(最优满二叉树) / 哈夫曼编码(贪心算法)
一 哈夫曼树 1.1 基本概念 算法思想 贪心算法(以局部最优,谋求全局最优) 适用范围 1 [(约束)可行]:它必须满足问题的约束 2 [局部最优]它是当前步骤中所有可行选择中最佳的局部选择 3 [ ...
- 使用F#来实现哈夫曼编码吧
最近算法课要求实现哈夫曼编码,由于前面的问题都是使用了F#来解决,偶然换成C#也十分古怪,报告也不好看,风格差太多.一开始是打算把C#版本的哈夫曼编码换用F#来写,结果写到一半就觉得日了狗了...毕竟 ...
随机推荐
- python with hadoop
python with hdfs hdfs 可以在 linux 本地操作 bin/hdfs dfs -ls /foo 但是这种只能在 命令行 操作. 通常我们需要在程序中实现远程操作,python ...
- Leaving Auction CodeForces - 749D (set,贪心,模拟)
大意: 若干个人参加拍卖会, 给定每个人出价顺序, 保证价格递增, q个询问, 给出k个人的编号, 求删除这k个人的所有出价后, 最终谁赢, 他最少出价多少. set维护每个人最后一次投票的时间, 每 ...
- 11.jQuery之自定义动画
注意:animate里面是一个对象,他有几个参数,详情可以参考官网 <style> div { position: absolute; width: 200px; height: 200p ...
- qt使用QWT注意事项
当继承某个QWT类时,有是使用O_OBJECT弘会出现问题 切记在工程文件里别忘了添加这一句 DEFINES+=QWT_DLL
- java学习笔记(5)多线程
一.简介(过段时间再写,多线程难度有点大) --------------------------------------- 1.进程:运行时的概念,运行的应用程序 2.线程:应用程序内部并发执行的代码 ...
- 本地安装node.js模块
一.需求 单位电脑不让上网,但是需要用到一个node.js模块,elasticdump. 二.解决 1.自己电脑上下载模块: npm install elasticdump -g 注意:必须要加 -g ...
- 在 sessionStorage存储json对象
目的:A页面存的东西要从B页面拿到 因为sessionStorage.setItem("key","value")内存储的都是字符串,所以,如果以对象的形式存到 ...
- Java函数优雅之道
https://www.cnblogs.com/amap_tech/p/11320171.html 导读 随着软件项目代码的日积月累,系统维护成本变得越来越高,是所有软件团队面临的共同问题.持续地优化 ...
- 接口测试参数化详解(Jmeter)
简介 接口测试是目前最主流的自动化测试手段,它组合不同的参数向服务器发送请求,接受和解析响应结果,通过测试数据的交换逻辑来验证服务端程序工作的正确性.我们在测试过程中需要考虑不同的输入组合,来覆盖不同 ...
- valgrind 性能测试工具学习使用
一.valgrind简介 Valgrind工具套件提供了许多调试和分析工具,可帮助您使程序更快,更正确.这些工具中最受欢迎的是Memcheck.它可以检测许多与C和C ++程序中常见的内存相关的错误, ...