哈夫曼树的学习以及实践

哈夫曼树

  • 哈夫曼树的基本了解
  • 哈夫曼树的基本概念
  • 创建霍夫曼树的思路
  • 编码构建的思路
  • 代码实现
    • 创建HuffmanTree结点
    • 初始化HuffmanTree
    • 创建霍夫曼树
    • 霍夫曼树编码

哈夫曼树的基本了解

给定 n 个 权值 作为 n 个 叶子节点,构造一颗二叉树,若该树的 带权路径长度(WPL)达到最小,称这样的二叉树为 最优二叉树,也称为 哈夫曼树(Huffman Tree),还有的叫 霍夫曼树

哈夫曼树的基本概念

  1. 路径 :从树中的一个结点到达另一个节点的分支结构构成的两个点之间的路径
  2. 路径长度:路径上的分支的数目(例如根结点为第一层,叶子节点为L层,那么根结点到叶子结点之间的路径长度为L-1)
  3. **树的路径长度:**从树的根结点到每个结点的路径长度之和
  4. :若将树中节点赋给一个有着某种函数的数值,则这个数值称为该节点的 权
  5. 结点的带权路径长度:从该结点到树根之间路径长度与该结点权重的乘积
  6. 树的带权路径长度:树中所有的叶子结点的带权路径长度之和
    在这里插入图片描述

创建霍夫曼树的思路

赫夫曼编码也翻译为 哈夫曼编码(Huffman Coding),又称霍夫曼编码,是一种 编码方式,,属于一种 程序算法
赫夫曼编码是 赫哈夫曼树 在电讯通信中的经典的应用之一。
赫夫曼编码广泛地用于 数据文件压缩。其压缩率通常在 20%~90% 之间
赫夫曼码是 可变字长编码(VLC) 的一种。Huffman 于 1952 年提出一种编码方法,称之为最佳编码
根据已经构建完成的赫夫曼树,给各个字符规定编码(前缀编码):
向左的路径为 0
向右的路径为 1

编码构建的思路

请添加图片描述
请添加图片描述

代码实现

创建HuffmanTree结点

#pragma region HuffmanTree的结构定义
typedef int datatype;
typedef struct HuffmanTree
{int weight;/*权重*/datatype data;int parent;int leftchild;int rightchild;
}HTNode;
typedef HuffmanTree* HuffTree;
#pragma endregion

初始化HuffmanTree

HuffTree InitHuffTree(int TreeNum)
{/*初始化树:首先创建存放2*TreeNum的存储空间的树,然后0下标位置不存放数据,从1位置开始赋值权重以及数据。*/HuffTree HT = NULL;HT = (HuffTree)malloc(sizeof(HTNode)*(2 * TreeNum));/*下标为0的HuffmanTree的结点是不用的*/for (int i = 1; i < 2*TreeNum; i++){HT[i].leftchild = -1;HT[i].rightchild = -1;HT[i].parent = -1;/*首先将双亲以及左右孩子置为-1*/}cout << "请输入权重" << endl;for (int i = 1; i <= TreeNum; i++){cin >> HT[i].weight;/*对每个结点赋值权重*/}char c = getchar();cout << "请输入数据" << endl;for (int i = 1; i <=TreeNum; i++){cin >> HT[i].data;}return HT;
}
#pragma endregion

创建霍夫曼树

void minvalue_select(HuffTree HT, int& minloction1, int& minloction2, int loc)
{int minvalue1 = MAXVALUE, minvalue2 = MAXVALUE;for (int i = 1; i < loc; i++){if ((minvalue1 > HT[i].weight)&&(HT[i].parent == -1)){minloction2 = minvalue1;minloction2 = minloction1;minvalue1 = HT[i].weight;minloction1 = i;}else{if ((HT[i].weight <minvalue2)&&(HT[i].parent == -1)){minvalue2 = HT[i].weight;minloction2 = i;}}}
}
HuffTree CreatHuffmanTree(HuffTree HT,int TreeNum)
{/*最终的parent为-1的结点代表根结点 没有双亲*/if (HT == NULL){cout << "HuffmanTree的数据为空 请重新输入" << endl;return NULL;}HuffTree tmpTree = NULL;tmpTree = HT;int minlocation1, minlocation2;for (int i = TreeNum+1; i <= TreeNum*2-1; i++){minvalue_select(tmpTree, minlocation1, minlocation2, i-1);/*找出两个最小的值*/HT[minlocation1].parent = HT[minlocation2].parent = i;HT[i].leftchild = minlocation1;HT[i].rightchild = minlocation2;/*其中location2大于location1*/HT[i].weight = HT[minlocation1].weight + HT[minlocation2].weight;}/*此时i也就是最后一个根结点 它的左右孩子已经确定 但是它的parent为-1 表示它为根结点*/return HT;
}
#pragma endregion

霍夫曼树编码

#pragma region 从叶子结点到根结点逆向求HuffmanTree编码
typedef char** HuffmanCode;
void HuffmanCoding(HuffTree HT, HuffmanCode& HC, int TreeNum)
{HC = (HuffmanCode)malloc(sizeof(char*)*TreeNum);/*表明HC是一个指针类型的变量,同时每一个指针存放的位置为一个char*类型的数据,也就表示HC是一个存放指针类型数据的指针数组*/if (HT==NULL){return;}char* tmpcode = (char*)malloc(sizeof(char)*TreeNum);if (tmpcode == NULL){return;}tmpcode[TreeNum -1 ] = '\0';HuffTree  tmpHTree = NULL;tmpHTree = HT;for (int i = 1; i <= TreeNum; i++){int location = TreeNum - 1;int parentIndex = tmpHTree[i].parent;int currentIndex = i;while (parentIndex !=-1)/*未到达根结点*/{if (tmpHTree[parentIndex].leftchild == currentIndex){tmpcode[--location] = '0';}else{tmpcode[--location] = '1';}currentIndex = parentIndex;parentIndex = tmpHTree[parentIndex].parent;}/*完成编码*/HC[i] = (char*)malloc(sizeof(char)*(TreeNum-location));if (HC[i]!=NULL){strcpy(HC[i], tmpcode + currentIndex);}cout << HC[i] << endl;}delete tmpcode;
}
#pragma endregion

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

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

相关文章

LeetCode:83和82.删除排序链表中的重复元素I,II

这两题算是链表的基础题&#xff0c;就遍历删除没啥特点&#xff0c; 83甚至不需要考虑第一个结点的特殊情况&#xff0c;属实是名副其实的easy了 LeetCode&#xff1a;21.合并两个有序链表之第一次的特殊情况-CSDN博客 83. 删除排序链表中的重复元素 - 力扣&#xff08;Lee…

TeamCity创建git项目Timed out 超时的一个解决办法

问题&#xff1a; 当自己&#xff1a; ping github.com从本地推送到远程仓库浏览器浏览www.github.com ——都没有问题 但是在teamcity创建工程的时候就超时&#xff1a; 或者多试几次&#xff0c;终于成功了&#xff0c;然后构建的时候半途超时报错。。。。。 一种解决办…

Vue3快速上手(四)ref之基本类型响应式数据

一、ref之基本类型响应式数据 1.1 基本语法 import { ref } from vuelet x ref(初始值)console.log(xxx --> , x.value);x为一个RefImpl对象&#xff0c;该对象的value属性为实际值&#xff0c;在script里需要操作x.value来改变数据的值&#xff0c;在页面里则可以直接使…

Django学习全纪录:创建第一个Django项目,如何使用Django开发⼀个web应用

导言 在上一篇文章里,我们对Django的开发环境进行了学习以及搭建,在上一篇文章里,同时也为大家介绍了安装、验证、修改默认镜像源等知识。 在这一篇文章里,我们就正式开始我们的Django开发之旅,创建我们的第一个项目,做一些较为简单且必需的前置工作。 如何创建Django项目…

【MySQL】学习约束和使用图形化界面创建表

&#x1f308;个人主页: Aileen_0v0 &#x1f525;热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 ​&#x1f4ab;个人格言:“没有罗马,那就自己创造罗马~” #mermaid-svg-iqtbME2KmWpQFQSt {font-family:"trebuchet ms",verdana,arial,sans-serif;font-siz…

RocksDB:高性能键值存储引擎初探

在现代的分布式系统和大数据应用中&#xff0c;一个高效、可靠的存储引擎是不可或缺的。RocksDB&#xff0c;由Facebook于2012年开发并随后开源&#xff0c;正是为了满足这类需求而诞生的。它是一个持久化的键值存储系统&#xff0c;特别适合在闪存&#xff08;Flash&#xff0…

HCIA-HarmonyOS设备开发认证V2.0-轻量系统内核基础-事件event

目录 一、事件基本概念二、事件运行机制三、事件开发流程四、事件使用说明五、事件接口坚持就有收获 一、事件基本概念 事件是一种实现任务间通信的机制&#xff0c;可用于实现任务间的同步&#xff0c;但事件通信只能是事件类型的通信&#xff0c;无数据传输。一个任务可以等…

Linux——网络通信TCP通信常用的接口和tco服务demo

文章目录 TCP通信所需要的套接字socket()bind()listen()acceptconnect() 封装TCP socket TCP通信所需要的套接字 socket() socket()函数主要作用是返回一个描述符&#xff0c;他的作用就是打开一个网络通讯端口&#xff0c;返回的这个描述符其实就可以理解为一个文件描述符&a…

代码随想录刷题笔记 DAY 25 | 组合问题 No.77 | 组合求和III No.216 | 电话号码的字母组合 No.17

文章目录 Day 2501. 组合问题&#xff08;No. 77&#xff09;2.1 题目2.2 笔记2.3 代码 02. 组合求和III&#xff08;No. 216&#xff09;2.1 题目2.2 笔记2.3 代码 03. 电话号码的字母组合&#xff08;No. 17&#xff09;3.1 题目3.2 笔记3.3 代码3.4 补充 Day 25 01. 组合问…

InstantBox:开箱即用的临时 Linux 环境

在云计算和虚拟化技术日益成熟的今天&#xff0c;我们有时需要一个快速、简单、临时的 Linux 环境来进行各种任务。这就是 InstantBox 的用武之地。 什么是 InstantBox&#xff1f; InstantBox 是一个开源项目&#xff0c;它可以快速启动临时的 Linux 系统&#xff0c;并提供…

微软Bing地图获取栅格瓦片或图块

bing地图获取栅格瓦片或图块 获取元数据 https://dev.virtualearth.net/REST/v1/Imagery/Metadata/{imagerySet}?key{BingMapsKey}imagerySet&#xff1a;要为其请求元数据的影像类型。官方说中国支持以下两个值&#xff1a;RoadOnDemand、VibrantDark BingMapsKey&#xff…

669. 修剪二叉搜索树

给你二叉搜索树的根节点 root &#xff0c;同时给定最小边界low 和最大边界 high。通过修剪二叉搜索树&#xff0c;使得所有节点的值在[low, high]中。修剪树 不应该 改变保留在树中的元素的相对结构 (即&#xff0c;如果没有被移除&#xff0c;原有的父代子代关系都应当保留)。…

【前沿技术杂谈:迁移学习】欧洲人工智能法案对人工智能开发者的意义 [2023 年 12 月更新]

【前沿技术杂谈&#xff1a;迁移学习】欧洲人工智能法案对人工智能开发者的意义 [2023 年 12 月更新&#xff3d; 定义、一般原则和禁止做法人工智能系统开发者基于风险的义务固定和通用人工智能开发人员&#xff08;第 3/28 条&#xff09;基础模型的提供者&#xff08;第 28b…

C++笔记:类与对象的语法

文章目录 1 简单认识面向过程与面向对象1.1 面向过程1.2 面向对象 2 类的引入&#xff1a;struct -> class3 类的定义3.1 class 定义类的语法3.2 成员变量的命名建议 4 类的访问限定符4.1 class 和 struct 的区别4.2 C更喜欢用class定义类的原因 5 类的作用域5.1 声明定义合…

Cost S-curve

成本S曲线 Cost S-curve 每个月成本预算&#xff0c;柱形图 每个月成本累积&#xff08;合计&#xff09;&#xff1a;成本S曲线&#xff0c;折线图&#xff0c;但是肯定都是上升的 echarts图表&#xff1a;

java客运管理系统Myeclipse开发mysql数据库web结构java编程计算机网页项目

一、源码特点 java客运管理系统是一套完善的java web信息管理系统&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为TOMCAT7.0,Myeclipse8.5开发&#xff0c;数据库为Mysql5.0&#…

Java实现中学生家校互联系统 JAVA+Vue+SpringBoot+MySQL

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 学生管理模块2.2 课堂表现模块2.3 考试成绩模块2.4 家校留言模块2.5 校园通知模块 三、系统设计3.1 用例设计3.2 实体类设计3.2.1 课堂表现实体类设计3.2.2 考试成绩实体类设计3.2.3 家校留言实体类设计3.2.4 校园通知实…

现代化端口扫描工具RustScan

今天是大年初五&#xff0c;喜迎财神 &#xff0c;祝大家✔️顺风顺水 ✔️诸事如意 ✔️财源滚滚 ✔️大吉大利 顺便提一下&#xff0c;老苏的博客启用了新域名&#xff1a; https://laosu.tech 什么是 RustScan &#xff1f; RustScan 是一款现代化的端口扫描器。能快速找到端…

AutoGen实战应用(三):多代理协作的数据可视化

之前我完成了关于AutoGen的两篇博客&#xff0c;还没有读过这两篇博客的朋友可以先阅读以下&#xff0c;这样有助于对AutoGen的初步了解&#xff1a; AutoGen实战应用(一)&#xff1a;代码生成、执行和调试_autogen 支持的model-CSDN博客 AutoGen实战应用(二)&#xff1a;多代…

Vue3.0(六):VueX 4.x详解

Vuex4状态管理 什么是状态管理 在开发中&#xff0c;我们的应用程序需要处理各种各样的数据&#xff0c;这些数据需要保存在应用程序的某一个位置&#xff0c;对于这些数据的管理&#xff0c;就是 状态管理目前前端项目越来越复杂&#xff0c;多组件共享同一数据的状态很常见…