一、什么是哈夫曼树

哈夫曼树又称为最优树.

通过权值来构造树,权值越大,离根节点越近

经常用于无损压缩算法

用于需要优化存储空间的场景

原理很简单,不多赘述

具体看百度百科的解释

需要注意 构建哈夫曼树不仅要值,还需要对应的权值

比如越常出现的,权值越大

二、构造哈夫曼树

通过权值来构造哈夫曼树

我画了几个图,具体过程如下

三、路径、编码、解码

上面通过权值构建了哈夫曼树,再将字符与权值对应起来

往左记作0 往右记作1

从根节点到各个叶子节点经过的0和1

就是该节点对应的路径

aaabbeaf编码:01010110101110011111

01010110101110011111解码:aaabbeaf

比如一个字符a原来占8位,通过哈夫曼编码后,就只占用2个位

但缺点是 权值较低的 占用字节会比较高,比如e,就占用4个位

四、代码

下面代码只是例子,编码解码并没有真的用位来表示,而是用字符串代替

HuffmanTree.h

#pragma once
#include<queue>
#include<iostream>
#include<algorithm>
#include<string>
using namespace std;
class HuffmanTree
{
struct Node
{
int weight;//权值
Node* left;//左孩子
Node* right;//右孩子
char value;//节点值
string path;//存放路径
}; //仅用于优先级队列比较
struct NodeCMP
{
bool operator()(Node* a, Node* b)
{
return a->weight > b->weight;
}
};
private:
Node* root = nullptr;
vector<pair<char, string>*>map;
public:
HuffmanTree(vector<int>& weight, vector<char>& value) {
createHuffmanTreeNode(weight,value);
createHuffmanTreePath();
}
//初始化节点
void createHuffmanTreeNode(vector<int>& weight, vector<char>& value) {
priority_queue<Node*,vector<Node*>, NodeCMP>que;//优先级队列构造树
for (size_t i = 0; i < weight.size(); i++){
Node* temp = new Node{ weight[i] ,nullptr,nullptr,value[i] };
que.push(temp);
}
while (que.size() >= 2){
Node* min1 = que.top();
que.pop();
Node* min2 = que.top();
que.pop();
Node* node = new Node{ min1->weight + min2->weight,min1,min2 };
que.push(node);
}
root = que.top();
}
//初始化路径
void createHuffmanTreePath() {
if (root == nullptr)return;
queue<Node*>que;
que.push(root);
while (que.size()){
Node* temp = que.front();
que.pop();
if (temp->left != nullptr) {
que.push(temp->left);
temp->left->path.append(temp->path + 0);
}
if (temp->right != nullptr){
que.push(temp->right);
temp->right->path.append(temp->path + 1);
}
if (temp->left == nullptr && temp->right == nullptr) {
map.push_back(new pair<char, string>(temp->value, temp->path));
}
}
}
string encode(string data) {
string result;
for (size_t i = 0; i < data.size(); i++) {
char ch = data[i];
for (size_t j = 0; j < map.size(); j++) {
pair<char, string>* mapData = map[j];
if (mapData->first == ch) {
result.append(mapData->second);
break;
}
}
}
return result;
}
string decode(string data) {
string result;
while (data.size())
{
for (size_t i = 0; i < map.size(); i++)
{
pair<char, string>* mapData = map[i];
if (data.find(mapData->second) == 0) {
result.push_back(mapData->first);
data = data.substr(mapData->second.size());
break;
}
}
}
return result;
} };

main.cpp

#include<iostream>
#include<vector>
#includeHuffmanTree.h
int main()
{
vector<int>weight = { 8,9,7,4,2,3 };
vector<char>value = { 'a','b','c','d','e','f'};
HuffmanTree tree(weight,value);
string str;
str = tree.encode(aaabbeaf);
cout << str << endl;
str = tree.decode(str);
cout << str << endl; return 0;
}

HuffmanTree,哈夫曼树的原理和c++实现的更多相关文章

  1. (哈夫曼树)HuffmanTree的java实现

    参考自:http://blog.csdn.net/jdhanhua/article/details/6621026 哈夫曼树 哈夫曼树(霍夫曼树)又称为最优树. 1.路径和路径长度在一棵树中,从一个结 ...

  2. 6-9-哈夫曼树(HuffmanTree)-树和二叉树-第6章-《数据结构》课本源码-严蔚敏吴伟民版

    课本源码部分 第6章  树和二叉树 - 哈夫曼树(HuffmanTree) ——<数据结构>-严蔚敏.吴伟民版        源码使用说明  链接☛☛☛ <数据结构-C语言版> ...

  3. 【算法】赫夫曼树(Huffman)的构建和应用(编码、译码)

    参考资料 <算法(java)>                           — — Robert Sedgewick, Kevin Wayne <数据结构>       ...

  4. 20172332 2017-2018-2 《程序设计与数据结构》Java哈夫曼编码实验--哈夫曼树的建立,编码与解码

    20172332 2017-2018-2 <程序设计与数据结构>Java哈夫曼编码实验--哈夫曼树的建立,编码与解码 哈夫曼树 1.路径和路径长度 在一棵树中,从一个结点往下可以达到的孩子 ...

  5. 【algo&ds】【吐血整理】4.树和二叉树、完全二叉树、满二叉树、二叉查找树、平衡二叉树、堆、哈夫曼树、B树、字典树、红黑树、跳表、散列表

    本博客内容耗时4天整理,如果需要转载,请注明出处,谢谢. 1.树 1.1树的定义 在计算机科学中,树(英语:tree)是一种抽象数据类型(ADT)或是实作这种抽象数据类型的数据结构,用来模拟具有树状结 ...

  6. 哈夫曼树详解——PHP代码实现

    在介绍哈夫曼树之前需要先了解一些专业术语 路径和路径长度 在一棵树中,从一个结点往下可以达到的孩子或孙子结点之间的通路,称为路径.通路中分支的数目称为路径长度.若规定根结点的层数为1,则从根结点到第L ...

  7. C++哈夫曼树编码和译码的实现

    一.背景介绍: 给定n个权值作为n个叶子结点,构造一棵二叉树,若带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman Tree).哈夫曼树是带权路径长度最短的树,权值较大的 ...

  8. 哈夫曼树(一)之 C语言详解

    本章介绍哈夫曼树.和以往一样,本文会先对哈夫曼树的理论知识进行简单介绍,然后给出C语言的实现.后续再分别给出C++和Java版本的实现:实现的语言虽不同,但是原理如出一辙,选择其中之一进行了解即可.若 ...

  9. 【数据结构】赫夫曼树的实现和模拟压缩(C++)

    赫夫曼(Huffman)树,由发明它的人物命名,又称最优树,是一类带权路径最短的二叉树,主要用于数据压缩传输. 赫夫曼树的构造过程相对比较简单,要理解赫夫曼数,要先了解赫夫曼编码. 对一组出现频率不同 ...

  10. Android版数据结构与算法(七):赫夫曼树

    版权声明:本文出自汪磊的博客,未经作者允许禁止转载. 近期忙着新版本的开发,此外正在回顾C语言,大部分时间没放在数据结构与算法的整理上,所以更新有点慢了,不过既然写了就肯定尽力将这部分完全整理好分享出 ...

随机推荐

  1. 【Azure 应用服务】Azure Function 部署槽交换时,一不小心把预生产槽上的配置参数交换到生产槽上,引发生产错误

    问题描述 部署Function代码先到预生产槽中,进行测试后通过交换方式,把预生产槽中的代码交换到生产槽上,因为在预生产槽中的设置参数值与生产槽有不同,但是在交换的时候,没有仔细检查.导致在交换的时候 ...

  2. C#的托盘窗体显示与隐藏效果 - 开源研究系列文章

    今天无聊,进行的C#的编码内容仍然在继续.这些天不断地在完善及编写C#的Winform相关的代码,并将其整理形成博文.这次带来的是关于窗体的显示及隐藏效果的代码段.上次有过一个代码,这次当做新代码进行 ...

  3. 【转载】很遗憾,没有一篇文章能讲清楚ZooKeeper

    作为分布式系统解决方案的 ZooKeeper,被广泛应用于多个分布式场景.例如:数据发布/订阅,负载均衡,命名服务,集群管理等等. 因此,ZooKeeper 在分布式系统中扮演着重要的角色,今天通过一 ...

  4. C++ //类模板分文件编写问题及解决 //第一中解决方式 直接包含源文件 //第二种解决方法 将.h 和 cpp的内容写到一起,将后缀改为.hpp文件

    1 //第一种方式被注释 2 //未被注释是第二种方式 3 //类模板分文件编写问题及解决 4 5 6 #include <iostream> 7 #include <string& ...

  5. Apollo获取配置异常:Load config failed, will retry in 1 SECONDS

    一.现象 apollo开启秘钥,服务获取配置参数需要启动参数中添加:jvm参数-Dapollo.accesskey.secret=XXX.日志如下: 二.解决方案 应用服务器时间异常,重置应用服务器时 ...

  6. STM32标准库通用定时器输入捕获

    STM32标准库定时器输入捕获 1.输入捕获介绍 输入捕获为STM32定时器的一个功能,可以用来测量输入信号的频率和占空比. 具体原理:当输入信号经过比较捕获通道时,STM32会依据通道的极性设置决定 ...

  7. Zabbix“专家坐诊”第185期问答汇总

    问题一 Q:Zabbix5.0版本,如图,请问这里怎么修改回localhost? A:找到文件conf/zabbix.conf.php,改下图这个位置 问题二 Q:大家好,我有个疑问请教下,zabbi ...

  8. 基于python的指定时段执行实例解析

    一 概念: python中库很多,这里熟悉下time和interval的用法 二 实例解析 切记这里的interval,输出的是目前的时间是一个数组. import time from interva ...

  9. day08-2-Thymeleaf

    服务器渲染技术-Thymeleaf 1.基本介绍 官方在线文档:Read online 文档下载:Thymeleaf 3.1 PDF, EPUB, MOBI Thymeleaf 是什么 Thymele ...

  10. tomcat无法启动的解决方法

    一:双击startup.bat但闪退 我们可以用记事本打开startup.bat 在末尾添加一个pause 这样它就会新建一个窗口停在错误的地方 二:根据报错信息改正 这一步如果有乱码可以进入tomc ...