【数据结构与算法】哈夫曼编码(最优二叉树)实现

哈夫曼编码

等长编码:占的位置一样

变长编码(不等长编码):经常使用的编码比较短,不常用的比较短

最优:总长度最短

最优的要求:占用空间尽可能短,不占用多余空间,且不能有二义性

这里给出哈夫曼二叉树的实现:

HuffmanTree.h:

#pragma oncetemplate <typename T>
class HuffmanTree {
public:HuffmanTree(int nCount, T* InData, int* InWeight);
private:typedef struct _HuffNode {T tValue;int weight;int n_lChild;int n_rChild;int n_Father;}Tree, *pTree;pTree m_pTreeRoot;int nTreeCount;
public:void show();void HuffmanCode(char** &InHuffmanCode,int nCount);
private:void select(int nCount, int* SmallValueA_Index, int* SmallValueB_Index);
};template<typename T>
inline HuffmanTree<T>::HuffmanTree(int nCount, T * InData, int* InWeight)
{nTreeCount = 2 * nCount;m_pTreeRoot = (pTree)calloc(nTreeCount + 1, sizeof(Tree));for (size_t i = 1; i <= nCount; i++) {m_pTreeRoot[i].tValue = InData[i-1];m_pTreeRoot[i].weight = InWeight[i-1];}for (size_t i = nCount + 1; i < nTreeCount; i++) {int SmallValueA_Index;int SmallValueB_Index;select(i - 1, &SmallValueA_Index, &SmallValueB_Index);m_pTreeRoot[SmallValueA_Index].n_Father = i;m_pTreeRoot[SmallValueB_Index].n_Father = i;m_pTreeRoot[i].n_lChild = SmallValueA_Index;m_pTreeRoot[i].n_rChild = SmallValueB_Index;m_pTreeRoot[i].weight = m_pTreeRoot[SmallValueA_Index].weight + m_pTreeRoot[SmallValueB_Index].weight;m_pTreeRoot[i].tValue = '0';}}template<typename T>
inline void HuffmanTree<T>::show()
{std::cout << "Index" << "   " << "Value" << "   " << "weight" << "   " << "ParentIndex" << "   " << "lChild" << "   " << "rChild" << "   " << std::endl;for (size_t i = 1; i < nTreeCount; i++) {printf("%-5.0d   %-5c   %-6d   %-11d   %-6d    %-6d\r\n", i, m_pTreeRoot[i].tValue, m_pTreeRoot[i].weight, m_pTreeRoot[i].n_Father, m_pTreeRoot[i].n_lChild, m_pTreeRoot[i].n_rChild); }
}template<typename T>
inline void HuffmanTree<T>::HuffmanCode(char **& InHuffmanCode, int nCount)
{InHuffmanCode = (char**)malloc(sizeof(char*)*(nCount + 1));char* code = (char*)malloc(nCount);code[nCount-1] = '\0';for (size_t i = 1; i <= nCount; i++) {int cha = i;int parent = m_pTreeRoot[i].n_Father;int start = nCount - 1;while (parent) {if (m_pTreeRoot[parent].n_lChild == cha) {code[--start] = '0';}else {code[--start] = '1';}cha = parent;parent = m_pTreeRoot[parent].n_Father;}InHuffmanCode[i] = (char*)malloc(nCount - start);strcpy(InHuffmanCode[i], &code[start]);}
}template<typename T>
inline void HuffmanTree<T>::select(int nCount, int * SmallValueA_Index, int * SmallValueB_Index)
{int nMin;for (size_t i = 1; i < nCount; i++) {if (m_pTreeRoot[i].n_Father == 0) {nMin = i;break;}}for (size_t i = nMin + 1; i <= nCount; i++) {if (m_pTreeRoot[i].n_Father == 0 && m_pTreeRoot[i].weight < m_pTreeRoot[nMin].weight) {nMin = i;}}*SmallValueA_Index = nMin;for (size_t i = 1; i <= nCount; i++){if (m_pTreeRoot[i].n_Father == 0 && i != *SmallValueA_Index){nMin = i;break;}}for (size_t i = nMin + 1; i <= nCount; i++){if (m_pTreeRoot[i].n_Father == 0 && m_pTreeRoot[i].weight < m_pTreeRoot[nMin].weight &&  i != *SmallValueA_Index){nMin = i;}}*SmallValueB_Index = nMin;
}

测试数据(主函数):

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <string>
#include "HuffmanTree.h"int main() {char a[] = { 'A','B','C','D','E','F' };int b[] = { 5,32,18,7,25,13 };HuffmanTree<char> arr(6, a, b);arr.show();char** HuffmanCode = nullptr;arr.HuffmanCode(HuffmanCode,6);std::cout << "编码值:" << std::endl;for (size_t i = 1; i <= 6; i++){printf("  %c:   %s\n",a[i-1],HuffmanCode[i]);}return 0;
}

运行结果截图:
哈夫曼二叉树
如果发现文章中有错误,还请大家指出来,我会非常虚心地学习,我们一起进步!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/4590.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C\C++ 使用ping判断ip是否能连通

文章作者&#xff1a;里海 来源网站&#xff1a;https://blog.csdn.net/WangPaiFeiXingYuan 简介&#xff1a; ping是一种用于测试网络连接的工具&#xff0c;它通过发送数据包到目标设备并等待其响应来工作&#xff0c;以检查网络是否连通。下面是例子. 效果&#xff1a; 代码…

JavaScript的WebAPI

这里写目录标题 DOM 基本概念获取元素事件概念事件的三要素操作元素获取/修改表单元素属性行内样式操作类名样式操作操作节点 DOM 基本概念 DOM 全称为 Document Object Model. W3C 标准给我们提供了一系列的函数, 让我们可以操作: 网页内容 ,网页结构, 网页样式 DOM数的结构如…

基于SpringBoot和Freemarker的用户管理系统

环境准备 JDK 1.8 及以上SpringBoot 2.5.5 及以上MySQL 5.7 及以上MavenIntelliJ IDEA &#xff08;可选&#xff09; 创建项目 我们使用 IntelliJ IDEA 创建一个 Spring Boot Web 项目。 打开 IntelliJ IDEA&#xff0c;点击菜单栏的 “File”&#xff0c;选择 “New”&…

vue2 element ui 的表格使用 sortablejs 拖拽列遇到的问题和解决方案

项目使用 element ui 的表格实现拖动表头可改变列的宽度&#xff0c;又使用sortablejs实现表格的列可拖拽到其他列的位置&#xff0c;导致出现如下的一些问题&#xff1a; 1、某一列宽变大或变小后&#xff0c;只有当前列可拖拽&#xff0c;其他列无法拖拽。 解决方案&#x…

软通动力与华秋达成生态共创合作,共同推动物联网硬件创新

7月11日&#xff0c;在2023慕尼黑上海电子展现场&#xff0c;软通动力信息技术(集团)股份有限公司(以下简称“软通动力”)与深圳华秋电子有限公司(以下简称“华秋”)签署了生态共创战略合作协议&#xff0c;共同推动物联网硬件生态繁荣发展。当前双方主要基于软通动力的产品及解…

【Python基础函数笔记】获取当前时间并写入日志

1.获取当前时间 import os from datetime import datetime import pytzdef get_cur_time():# 获取当前时间return datetime.strftime(datetime.now(pytz.timezone(Asia/Singapore)), %Y-%m-%d_%H-%M-%S)# 基础目录 basedir a logdir os.path.join(basedir, logs, str(args.n…

docker push镜像到自己的hub仓库

注册docker hub的账户 https://hub.docker.com/建立自己的仓库在终端执行 docker login给想要推送的镜像打标签 docker tag localimage:tag iamajdocker(账号名)/myrepository(仓库名):tag(dockerhub上显示的镜像名)例如&#xff1a; hub用户名为xx,在hub建立的仓库名为evmos…

Spring Cloud—GateWay之限流

RequestRateLimiter RequestRateLimiter GatewayFilter 工厂使用 RateLimiter 实现来确定是否允许当前请求继续进行。如果不允许&#xff0c;就会返回 HTTP 429 - Too Many Requests&#xff08;默认&#xff09;的状态。 这个过滤器需要一个可选的 keyResolver 参数和特定于…

pyqt 简单案例

一、空白的widget窗口 import sys from PyQt5 import QtWidgets,QtCoreapp QtWidgets.QApplication(sys.argv) widget QtWidgets.QWidget() widget.resize(360,360) widget.setWindowTitle("helloword") widget.show() sys.exit(app.exec_()) 需要引入sys模块&…

docker - 将tar包加载成镜像

这部分, 先从这篇开始吧, 然后根据相关工作顺序再慢慢介绍~ 介绍: 一般构建我们自己的镜像有很多方式, 这里介绍根据tar包进行构建镜像images. 用法: 加载镜像的tar包, 在服务器生成对应的镜像images: sudo docker load -i /home/xxx/tar_name.tar参数介绍: /home/xxx/ta…

STL源码刨析_stack _queue

目录 一. 介绍 1. stack 介绍 2. queue 介绍 二. 模拟实现 1. stack 模拟实现 2. queue 模拟实现 三. deque 1. deque 接口 2. 底层 一. 介绍 1. stack 介绍 stack&#xff08;栈&#xff09;是一种容器适配器&#xff0c;它提供了一种后进先出&#xff08;LIFO&#xff0…

VMware安装Ubuntu(VMware版本17-Ubuntu版本16.0)

VMware安装Ubuntu&#xff08;VMware版本17-Ubuntu版本16.0&#xff09; 一&#xff0c;VMware虚拟机下载官网点击https://customerconnect.vmware.com/cn/downloads/info/slug/desktop_end_user_computing/vmware_workstation_pro/17_0 二&#xff0c;Ubuntu乌班图下载官网点…

VB旅游资源及线路管理系统的设计与实现

旅游作为一个新兴的产业近年来取得了迅速的发展,旅行社如雨后春笋遍布全国各省市、目前旅游行业普遍存在着企业规模小,管理不规范等弱点。因为旅游涉及吃、住、行、游、购、娱等诸多要素,而且这些要素又分散在不同的地域中,一个人不可能全面掌握所有的信息。一旦掌握某方面…

会议OA项目之会议发布(多功能下拉框的详解)

&#x1f973;&#x1f973;Welcome Huihuis Code World ! !&#x1f973;&#x1f973; 接下来看看由辉辉所写的关于OA项目的相关操作吧 目录 &#x1f973;&#x1f973;Welcome Huihuis Code World ! !&#x1f973;&#x1f973; 一.主要功能点介绍 二.效果展示 三.前…

[极客大挑战 2019]PHP(反序列化)

介绍说明&#xff0c;有备份的习惯&#xff0c;找常见的备份文件后缀名 使用dirsearch进行扫描 dirsearch -u http://f64378a5-a3e0-4dbb-83a3-990bb9e19901.node4.buuoj.cn:81/ -e php-e 指定网站语言 扫描出现&#xff0c;www.zip文件 查看index.php <?php include c…

ES(3)映射关系

文章目录 创建映射关系更具映射关系创建数据查询有什么区别呢&#xff1f; 创建映射关系 创建mapping映射类似于我们创建表结构&#xff0c;规定字段什么类型&#xff0c;多长等基本信息。 先创建 索引 PUT http://127.0.0.1:9200/user 然后创建映射关系 PUT http://127.0.…

[运维] 生成nginx 自签名ssl证书

系统说明 Ubuntu 22.04 STL 服务器版 生成证书 要生成 Nginx SSL 证书&#xff0c;你可以使用 OpenSSL 工具。按照以下步骤操作&#xff1a; 安装 OpenSSL&#xff1a; 如果你的系统上还没有安装 OpenSSL&#xff0c;请使用以下命令安装它&#xff1a; sudo apt update su…

C++-----vector

本期我们来学习C中的vector&#xff0c;因为有string的基础&#xff0c;所以我们会讲解的快一点 目录 vector介绍 vector常用接口 构造函数 sort 迭代器 size&#xff0c;max_size&#xff0c;capacity&#xff0c;empty reserve和resize front和back data insert和…

MATLAB 基于CPD的点云配准 (24)

MATLAB 基于CPD的点云配准 (24) 一、算法简介二、具体使用1.代码(注释详细)2.函数介绍3.使用技巧4.重复叠加配准效果如何一、算法简介 MATLAB 中包含了一种基于CPD的点云配准方法,这里对其进行使用,查看其配准效果,结果来看如上图所示,还是可用的。 二、具体使用 1.代…

快7月底了,让我康康有多少准备跳槽的

前两天跟朋友感慨&#xff0c;今年的铜三铁四、裁员、疫情影响导致好多人都没拿到offer!现在已经快7月底了&#xff0c;具体金九银十只剩下2个月。 对于想跳槽的职场人来说&#xff0c;绝对要从现在开始做准备了。这时候&#xff0c;很多高薪技术岗、管理岗的缺口和市场需求也…