GDPU 数据结构 天码行空9

news2024/11/26 16:35:37

实验九 哈夫曼编码

一、【实验目的】

1、理解哈夫曼树的基本概念
2、掌握哈夫曼树的构造及数据结构设计
3、掌握哈夫曼编码问题设计和实现

二、【实验内容】

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)输出编码。

三、【实验源代码】

#include <iostream>
using namespace std;
#include <cstdio>
#include <cstring>
typedef struct node {   //哈夫曼树中单个节点的信息
    int parent;   //父节点
    char letter;   //字母
    int lchild;
    int rchild;
    double weight;   //权值
}*HuffmanTree;
void Select(HuffmanTree& tree, int n, int& s1, int& s2) {   //找到权值最小的两个值的下标,其中s1的权值小于s2的权值
    int min = 0;
    for (int i = 1; i <= n; i++) {
        if (tree[i].parent == 0) {
            min = i;
            break;
        }
    }
    for (int i = min + 1; i <= n; i++) {
        if (tree[i].parent == 0 && tree[i].weight < tree[min].weight)
            min = i;
    }
    s1 = min;   //找到第一个最小值,并赋给s1
    for (int i = 1; i <= n; i++) {
        if (tree[i].parent == 0 && i != s1) {
            min = i;
            break;
        }
    }
    for (int i = min + 1; i <= n; i++) {
        if (tree[i].parent == 0 && i != s1 && tree[i].weight < tree[min].weight)
            min = i;
    }
    s2 = min;  //找到第二个最小值,并赋给s2
}
void CreateHuff(HuffmanTree& tree, char* letters, double* weights, int n) {
    int m = 2 * n - 1;   //若给定n个数要求构建哈夫曼树,则构建出来的哈夫曼树的结点总数为2n-1
    tree = (HuffmanTree)calloc(m + 1, sizeof(node));   //开辟空间顺序储存Huffman树,用calloc开辟的空间初始化的值为0(NULL),符合Huffman树初始化条件(parent、weight、lchild、rchild等初始化应为0),由于tree[0]不存数据(因为任何节点的父节点若为0,会与节点初始化0值相混淆,故不存数据),则要开辟(2n-1)+1个空间(额外开辟一个空间)
    for (int i = 1; i <= n; i++) {   //给节点赋字母及其对应的权值
        tree[i].weight = weights[i - 1];
        tree[i].letter = letters[i];
    }
    for (int i = n + 1; i <= m; i++) {
        int s1 = 0, s2 = 0;
        Select(tree, i - 1, s1, s2);   //每次循环选择权值最小的s1和s2,生成它们的父结点
        tree[i].weight = tree[s1].weight + tree[s2].weight;   //新创建的节点i 的权重是s1和s2的权重之和
        tree[i].lchild = s1;   //新创建的节点i 的左孩子是s1
        tree[i].rchild = s2;   //新创建的节点i 的右孩子是s2
        tree[s1].parent = i;   //s1的父亲是新创建的节点i
        tree[s2].parent = i;   //s2的父亲是新创建的节点i
    }   
}
void HuffmanCoding(HuffmanTree& tree, char**& HuffCode, int n) {
    HuffCode = (char**)malloc(sizeof(char*) * (n + 1));   //运用char型二级指针,可理解成包含多个char*地址的数组,开n+1个空间,因为下标为0的空间不用
    char* tempcode = (char*)malloc(sizeof(char) * n);
    tempcode[n - 1] = '\0';
    for (int i = 1; i <= n; i++) {
        int start = n - 1;
        int doing = i;   //doing为正在编码的数据节点
        int parent = tree[doing].parent;   //找到该节点的父结点
        while (parent) {   //直到父结点为0(NULL),即父结点为根结点时停止
            if (tree[parent].lchild == doing)   //如果该结点是其父结点的左孩子,则编码为0,否则为1
                tempcode[--start] = '0';
            else
                tempcode[--start] = '1';
            doing = parent;   //继续往上进行编码
            parent = tree[parent].parent;
        }
        HuffCode[i] = (char*)malloc(sizeof(char) * (n - start));   //开辟用于存储编码的内存空间
        strcpy(HuffCode[i], &tempcode[start]);   //将编码拷贝到字符指针数组中的相应位置
    }
    free(tempcode); //释放辅助空间
}
int main() {
    int n = 8;
    char letters[9] = {' ','a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'};
    double weights[9] = {0.07, 0.19, 0.02, 0.06, 0.32, 0.03, 0.21, 0.10};
    HuffmanTree tree;
    CreateHuff(tree, letters, weights, n);   //构建哈夫曼树
    char** HuffCode;
    HuffmanCoding(tree, HuffCode, n);
    for (int i = 1; i <= n; i++)
        printf("字母 %c 的哈夫曼编码值是: %s\n", tree[i].letter, HuffCode[i]);
    return 0;
}

👨‍🏫 参考资料

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

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

相关文章

拍摄视频的时候相机断电导致视频文件损坏,怎么修复

3-4 现在好多人都有自己的相机&#xff0c;但是专业用来录像的机器应该是不太可能都有的&#xff0c;相机的稳定性会比专业的机器差一些&#xff0c;如果用于比较重要的场景&#xff0c;比如婚庆、会议录像、家庭录像使用等&#xff0c;有较少的概率会出现一些奇怪的情况&…

mysql千万数据快速插入-实战

文章目录 前言环境一、配置二、效果总结 前言 数据量太大了&#xff0c;每天半夜要同步很大数据到 mysql 数据库&#xff0c;其中一张表就上2千万&#xff0c;总计上亿条数据。同步任务每天0点之后开始任务&#xff08;因为到0之后才能统计前一天数据&#xff09;&#xff0c;…

Matlab设置figure中标题/图例英文不同字体

1.创建一个曲线图 x linspace(-10,10,200); y sin(4*x)./exp(x); plot(x,y) xlim([0 10]) ylim([-0.4 0.8]) xlabel(a); ylabel(b); title(曲线图sapi); set(gca,FontName,Times New Roman,fontsize,16); legend(曲线12)标题中既包含英文又包含中文&#xff0c;如果设置字体…

selenium xpath定位

selenium-xpath定位 <span style"background-color:#2d2d2d"><span style"color:#cccccc"><code class"language-javascript">element_xpath <span style"color:#67cdcc"></span> driver<span styl…

java中的对象克隆(浅克隆和深克隆)

在实际项目中&#xff0c;一个模型类需要为不同的层提供不同的模型。VO DO DTO 需要将一个对象中的数据克隆到其他对象中。 误区&#xff1a;这种形式的代码复制的是引用&#xff0c;即对象在内存中的地址&#xff0c;stu1和stu2两个引用指向的是同一个对象 Student stu1 new…

【c++】——类和对象(中)——赋值运算符重载

作者:chlorine 专栏:c专栏 你站在原地不动,就永远都是观众。 【学习目标】 拷贝复制——赋值运算符重载 目录 &#x1f393;运算符重载的初步认识 &#x1f308;运算符重载 &#x1f308;赋值运算符重载格式 (上) &#x1f308;operator__判断俩个日期是否相等 &#x…

万宾科技智能井盖,实现对井盖的监测

随着人工智能和物联网技术的不断变化&#xff0c;各种适用于市政府提高管理能力和公共服务水平的高科技产品不断更新。在道路基础设施建设过程中&#xff0c;智能井盖传感器的出现时刻保护着城市地下生命线&#xff0c;而且可以对地下水道井盖进行实时的监测并完成数据上传等工…

Elastic Observability 8.11:ES|QL、APM 中的通用分析和增强的 SLOs

作者&#xff1a;Tom Grabowski, Katrin Freihofner, Israel Ogbole Elastic Observability 8.11 引入了 ES|QL for Observability&#xff08;技术预览版&#xff09;、Universal ProfilingTM 和 Elastic APM 集成&#xff0c;以及针对 Elastic Observability 的新 SLO &#…

判断sparse matrix是否是对称矩阵

参考&#xff1a; https://stackoverflow.com/questions/48798893/error-in-checking-symmetric-sparse-matrix import scipy.sparse as sp import numpy as np np.random.seed(1)a sp.random(5, 5, density0.5)a结果如下 sym_err a - a.T sym_check_res np.all(np.abs(s…

docker influxdb

docker & influxdb 搜索镜像 docker search influxdb docker pull influxdb: 1.4.2 docker run -d -p 8086:8086 --name influxdb influxdb:1.4.2 docker exec -it influxdb bash 连接influxdb 控制台 influx -host localhost -port 8086 influx -username root -passw…

docker部署mongodb

1&#xff1a;拉去momgodb镜像 2&#xff1a;拉去成功后&#xff0c;通过docker-compose.yml配置文件启动mongodb&#xff0c;docker-compose.yml配置如下 version: 3.8 services:mongodb-1:container_name: mongodbimage: mongo ports:- "27017:27017"volumes:- G:…

ESP8266 WiFi模块快速入门指南

ESP8266是一种低成本、小巧而功能强大的WiFi模块&#xff0c;非常适合于物联网和嵌入式系统应用。本指南将为您提供关于ESP8266 WiFi模块的快速入门步骤和基本知识。 第一步&#xff1a;硬件准备 首先&#xff0c;您需要将ESP8266 WiFi模块与您的开发板连接。通常情况下&#…

简单好看个人引导页毛玻璃页面 HTML 源码

毛玻璃个人引导页源码&#xff0c;界面简洁&#xff0c;已测可完美搭建&#xff0c;UI非常不错的&#xff0c;有兴趣的自行去安装体验吧&#xff0c;其它就没什么好介绍的了。 学习资料源代码&#xff1a;百度网盘 请输入提取码&#xff1a;ig8c

代挂单页网址发布页+加盟代理+APP下载页源码

代挂单页加盟代理网址发布页app下载页HTML单页版本&#xff0c;自行修改源码内文字。自行修改联系方式、登录地址&#xff01;上传即可使用。源码我已全部打包好&#xff0c;直接上传本站提供的源码&#xff0c;无后台&#xff0c;直接访问即可&#xff01; 源码下载&#xff…

Termius for Mac:掌控您的云端世界,安全高效的SSH客户端

你是否曾经在Mac上苦苦寻找一个好用的SSH客户端&#xff0c;让你能够远程连接到Linux服务器&#xff0c;轻松管理你的云端世界&#xff1f;现在&#xff0c;我们向你介绍一款强大而高效的SSH客户端——Termius。 Termius是一款专为Mac用户设计的SSH客户端&#xff0c;它提供了…

SPASS-探索性分析

探索性分析的意义 探索性分析更加强大,它是一种在对资料的性质、分布特点等完全不清楚的情况下,对变量进行更深入研究的描述性统计方法。在进行统计分析前,通常需要寻求和确定适合所研究的问题的统计方法, SPSS提供的探索性分析是解决此类问题的有效办法 探索性分析提供了很…

Vue3全局共享数据

目录 1&#xff0c;Vuex2&#xff0c;provide & inject2&#xff0c;global state4&#xff0c;Pinia5&#xff0c;对比 1&#xff0c;Vuex vue2 的官方状态管理器&#xff0c;vue3 也是可以用的&#xff0c;需要使用 4.x 版本。 相对于 vuex3.x&#xff0c;有两个重要变…

Hive 常用存储、压缩格式

1. Hive常用的存储格式 TEXTFI textfile为默认存储格式 存储方式&#xff1a;行存储 磁盘开销大 数据解析开销大 压缩的text文件 hive 无法进行合拆分 SEQUENCEFILE sequencefile二进制文件&#xff0c;以<key,value>的形式序列到文件中 存储方式&#xff1a;行存储 可…

贾扬清开源 AI 框架 Caffe | 开源英雄

【编者按】在开源与人工智能的灿烂星河里&#xff0c;贾扬清的名字都格外地耀眼。因为导师 Trevor Darrell 教授的一句“你是想多花时间写一篇大家估计不是很在意的毕业论文&#xff0c;还是写一个将来大家都会用的框架&#xff1f;”&#xff0c;学生贾扬清一头扎进了创 Caffe…

零代码+分布式微服务架构打造新一代一站式服务集成平台

目 录 01 项目背景 02 普元ESB产品介绍 03 新版本功能特性 04 应用案例‍‍‍‍ 05 展望与发展 01 项目背景 企业在实现数字化转型的过程中&#xff0c;随着信息化程度的提高&#xff0c;越来越多的企业开始采用微服务架构来构建自己的业务系统,各种系统之间的集成、数据共享…