【GDPU】数据结构实验十 哈夫曼编码

【实验内容】


1、假设用于通信的电文仅由8个字母 {a, b, c, d, e, f, g, h} 构成,它们在电文中出现的概率分别为{ 0.07, 0.19, 0.02, 0.06, 0.32, 0.03, 0.21, 0.10 },试为这8个字母设计哈夫曼编码。

提示:包含两个过程:1)构建哈夫曼树,(2)输出编码。


我的思路:

1建造哈夫曼树的过程直接按照哈夫曼思想模拟即可

2)输出编码。而 哈夫曼编码函数,我使用了 图论中的 dfs回溯算法 的思想,采用以 递归为 核心的方法遍历整棵树,并将走过的左路径标记为 0,将走过的右路径标记为 1,到了叶子节点收集路径结果,

每一条路径我使用 一维数组 path 记录

全部路径的结果,我使用 二维数组 result 存储

最后打印 result  数组即可


简而言之:

用一维数组记录路径 上的 0 和 1,到了叶子节点就成为一条完整的编码

将每一条编码用  二维数组 存起来


头文件 Head.h

建造一棵哈夫曼树的相关函数和操作

#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#define MAX 40// 创建树节点
typedef struct HtNode {int ww;int parent, Lchild, Rchild;
}HtNode;// 哈夫曼树结构
typedef struct HtTree {int root;HtNode ht[MAX];
}PHtTree;// 构造哈夫曼树
// m 为权值节点数量,w 为权值数组
PHtTree* CreateHuffMan(int m, int* w) {// 创建带有 m 个叶子节点的哈夫曼树PHtTree* pht = (PHtTree*)malloc(sizeof(PHtTree));if (pht == NULL) {perror("malloc fail !");return NULL;}// 初始化for (int i = 0; i < 2 * m - 1; ++i) {pht->ht[i].Lchild = pht->ht[i].Rchild = pht->ht[i].parent = -1;// 将数组前 m 个位置放入 权值数组元素if (i < m)pht->ht[i].ww = w[i];elsepht->ht[i].ww = -1;}// 构建哈夫曼树int i;for (i = 0; i < m - 1; i++) {// 两个m 找最小权值,两个 index 记录这两节点的下标int m1, m2, index1, index2;m1 = m2 = INT_MAX;index1 = index2 = -1;// 每轮都在区间 [0,  m + i] 找两个最小权值节点,且没有父节点(即没有使用过)for (int j = 0; j < m + i; ++j) {if (pht->ht[j].ww < m1 && pht->ht[j].parent == -1) {m2 = m1;index2 = index1;m1 = pht->ht[j].ww;index1 = j;}else if (pht->ht[j].ww < m2 && pht->ht[j].parent == -1) {m2 = pht->ht[j].ww;index2 = j;}}// 找到节点之后,构建父节点,并将父节点放进数组中pht->ht[index1].parent = m + i;pht->ht[index2].parent = m + i;pht->ht[m + i].ww = m1 + m2;pht->ht[m + i].Lchild = index1;pht->ht[m + i].Rchild = index2;}pht->root = m + i; // 更新根节点:m+i 即为 m + (m-2)return pht;
}

哈夫曼编码函数  HuffmanEncode

#include"Head.h"// 哈夫曼编码
// 思路:遍历每一条路,到叶子节点记录结果,左边标记为 0, 右边标记为 1// p  遍历 path :从下标 1 开始存放编码串,下标 0 存放字符串长度(表示该编码串长度,方便遍历)
// r 遍历 result:代表一一存放结果
int r = 0, p = 1;  
int result[MAX][MAX];  // 收集 path 的每一次结果
int path[MAX];   // 记录每一条路径的编码void HuffmanEncode(HtNode* ht, int root)
{if (root == -1) return; // 空节点返回if (ht[root].Lchild == -1 && ht[root].Rchild == -1) { // 叶子节点 就记录结果path[0] = p - 1;  // p-1 代表此时 path数组中收集的 路径上的(一串 1 和 0)的数量:方便遍历,因为每一串编码不等长,所以需要记录数量memcpy(result + r, path, sizeof(int)*p);  // 将一维数组 path 存放进二维数组 result :记录每一条路径的最终结果r++;path[0] = 0;  // 将第 0 个位置重新置为 0(表示恢复之前的状态)return;}path[p++] = 0;  // 向左走路径标记为 0HuffmanEncode(ht, ht[root].Lchild); // 递归到左节点p--;  // 从左节点回退回来:p-- 代表将 path[p++] = 0;   这里曾经标记的 0 给"删除"path[p++] = 1;  // 路径标记为 1HuffmanEncode(ht, ht[root].Rchild); // 递归到右节点p--;   // 从右节点回退回来:p-- 代表将 path[p++] = 1;   这里曾经标记的 1 给"删除"}

主函数 Main.c 

int main()
{// 输入 m 和 w 数组int m, w[MAX];scanf("%d", &m);float t = 0;for (int i = 0; i < m; ++i) {scanf("%f", &t);w[i] = t * 100;  // 浮点树先乘上倍数,变成整型,方便计算}// 构建一棵树PHtTree* pht = CreateHuffMan(m, w);HuffmanEncode(pht->ht, pht->root - 1); // 传数组过去就可以了// 打印每一编码printf("\n");for (int i = 0; i < m; ++i) {int x = result[i][0];for (int j = 1; j <= x; ++j) {printf("%d ", result[i][j]);}printf("\n");}return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

python菜鸟级安装教程 -下篇(安装编辑器)

来来~接着上篇的来~ 安装好python.exe之后&#xff0c;我们可以根据cmd命令窗口&#xff0c;码代码。 这算最简单入门了~ 如果我们在安装个编辑器。是什么效果&#xff0c;一起体验一下吧 第一步&#xff0c;下载编辑器&#xff0c;选择官网&#xff0c;下载免费版本入门足…

详细分析Mybatis与MybatisPlus中分页查询的差异(附Demo)

目录 前言1. Mybatis2. MybatisPlus3. 实战 前言 更多的知识点推荐阅读&#xff1a; 【Java项目】实战CRUD的功能整理&#xff08;持续更新&#xff09;java框架 零基础从入门到精通的学习路线 附开源项目面经等&#xff08;超全&#xff09; 本章节主要以Demo为例&#xff…

Vulnhub项目:ICA: 1

1、靶机介绍 靶机地址&#xff1a;ICA: 1 ~ VulnHub 2、渗透过程 首先&#xff0c;部署好靶机后&#xff0c;进行探测&#xff0c;发现靶机ip和本机ip&#xff0c;靶机ip156&#xff0c;本机ip146。 然后查看靶机ip有哪些端口&#xff0c;nmap一下。 出现22、80、3306端口&a…

书生·浦语大模型实战营之手把手带你评测 Llama 3 能力(OpenCompass 版)

书生浦语大模型实战营之手把手带你评测 Llama 3 能力&#xff08;OpenCompass 版&#xff09; 环境配置 conda create -n llama3 python3.10 pytorch torchvision pytorch-cuda -c nvidia -c pytorch -y conda activate llama3conda install git git-lfs install✨下载 Llama3…

贪心问题 难度[普及-]一赏

目录 #小A的糖果 删数问题 陶陶摘苹果&#xff08;升级版&#xff09; P5019 NOIP2018 提高组 铺设道路 小A的糖果 原文链接: P3817 小A的糖果 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 题目描述 小 A 有 n 个糖果盒&#xff0c;第 i 个盒中有 a_i 颗糖果。 小 A 每…

用PowerPoint创建毛笔字书写动画

先看看下面这个毛笔字书写动画&#xff1a; 这个动画是用PowerPoint创建的。下面介绍创建过程。 1、在任何一款矢量图片编辑软件中创建一个图片&#xff0c;用文字工具输入文字内容。我用的是InkScape。排好版后将图片保存为.svg格式的矢量图片文件。 2、打开PowerPoint&…

openEuler 22.03 GPT分区表模式下磁盘分区管理

目录 GPT分区表模式下磁盘分区管理parted交互式创建分区步骤 1 执行如下步骤对/dev/sdc磁盘分区 非交互式创建分区步骤 1 输入如下命令直接创建分区。 删除分区步骤 1 执行如下命令删除/dev/sdc1分区。 GPT分区表模式下磁盘分区管理 parted交互式创建分区 步骤 1 执行如下步骤…

【刷题篇】双指针(一)

文章目录 1、移动零2、复写零3、快乐数4、盛最多水的容器 1、移动零 给定一个数组 nums&#xff0c;编写一个函数将所有 0 移动到数组的末尾&#xff0c;同时保持非零元素的相对顺序。 请注意 &#xff0c;必须在不复制数组的情况下原地对数组进行操作。 class Solution { pub…

SRC公益漏洞挖掘思路分享

0x00 前言 第一次尝试挖SRC的小伙伴可能会觉得挖掘漏洞非常困难&#xff0c;没有思路&#xff0c;不知道从何下手&#xff0c;在这里我分享一下我的思路 0x01 挖掘思路 确定自己要挖的漏洞&#xff0c;以及该漏洞可能存在的功能点&#xff0c;然后针对性的进行信息收集 inurl…

[1726]java试飞任务规划管理系统Myeclipse开发mysql数据库web结构java编程计算机网页项目

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

延时任务通知服务的设计及实现(三)-- JDK的延迟队列DelayQueue

一、接着上文 上文我们讲述了使用redisson的RDelayedQueue实现分布式延迟队列&#xff0c;本文我们将自己JDK的延迟队列DelayQueue实现。 相比前者的实现&#xff0c;作为进程内的延迟队列&#xff0c;它会遇到许多技术难点&#xff1a; 如何支持分布式的多个节点部署场景应…

matplotlib和pandas与numpy

1.matplotlib介绍 一个2D绘图库&#xff1b; 2.Pandas介绍&#xff1a; Pandas一个分析结构化数据的工具&#xff1b; 3.NumPy 一个处理n纬数组的包&#xff1b; 4.实践&#xff1a;绘图matplotlip figure()生成一个图像实例 %matplotlib inline&#xff1a;图形直接在…

就业班 第三阶段(redis) 2401--5.7 day2 redis2 哨兵(前提是做好了主从)+redis集群

1、设置密码&#xff08;redis&#xff09; 先在redis.conf里面找到这个 后面写上要设置的密码即可 2、哨兵模式 监控redis集群中master状态的的工具 在做了主从的前提下 主 从1 从2 作用 1)&#xff1a;Master状态检测 2)&#xff1a;如果Master异常&#xff0c;则会进行…

Linux--基础IO(文件描述符fd)

目录 1.回顾一下文件 2.理解文件 下面就是系统调用的文件操作 文件描述符fd&#xff0c;fd的本质是什么&#xff1f; 读写文件与内核级缓存区的关系 据上理论我们就可以知道&#xff1a;open在干什么 3.理解Linux一切皆文件 4.C语言中的FILE* 1.回顾一下文件 先来段代码…

数据结构——链表(精简易懂版)

文章目录 链表概述链表的实现链表的节点&#xff08;单个积木&#xff09;链表的构建直接构建尾插法构建头插法构建 链表的插入 总结 链表概述 1&#xff0c;链表&#xff08;Linked List&#xff09;是一种常见的数据结构&#xff0c;用于存储一系列元素。它由一系列节点&…

Mysql查询语句(一)简单查询和简单条件查询

MySQL的所有语句中&#xff0c;我们日常用的最多的其实就是查询语句。因此这篇文章主要介绍查询语句中的一些基础语法。 目录 简单查询 简单条件查询 简单查询 最简单的查询语句的语法如下所示&#xff1a; SELECT * FROM student; 它的语法解析如下&#xff1a; SELECT关…

学习笔记:【QC】Android Q qmi扩展nvReadItem/nvWriteItem

一、qmi初始化 流程图 初始化流程: 1、主入口&#xff1a; vendor/qcom/proprietary/qcril-hal/qcrild/qcrild/rild.c int main(int argc, char **argv) { const RIL_RadioFunctions *(*rilInit)(const struct RIL_Env *, int, char **); rilInit RIL_Init; funcs rilInit…

122. Kafka问题与解决实践

文章目录 前言顺序问题1. 为什么要保证消息的顺序&#xff1f;2.如何保证消息顺序&#xff1f;3.出现意外4.解决过程 消息积压1. 消息体过大2. 路由规则不合理3. 批量操作引起的连锁反应4. 表过大 主键冲突数据库主从延迟重复消费多环境消费问题后记 前言 假如有家公司是做餐饮…

无法添加以供审核,提交以供审核时遇到意外错误。如果问题仍然存在,请联系我们

遇到问题&#xff1a; 无法添加以供审核 要开始审核流程&#xff0c;必须提供以下项目&#xff1a; 提交以供审核时遇到意外错误。如果问题仍然存在&#xff0c;请联系我们。 解决办法&#xff1a; 修改备案号为小写&#xff0c; 例如&#xff1a;京ICP备2023013223号-2A 改…

自然语言(NLP)

It’s time for us to learn how to analyse natural language documents, using Natural Language Processing (NLP). We’ll be focusing on the Hugging Face ecosystem, especially the Transformers library, and the vast collection of pretrained NLP models. Our proj…