GDPU 数据结构 天码行空9

实验九 哈夫曼编码

一、【实验目的】

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;
}

👨‍🏫 参考资料

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

华为云,阿里云,腾讯云 安全组配置规则

1.安全组常用端口 端口服务说明21FTPFTP服务所开放的端口&#xff0c;用于上传、下载文件。22SSHSSH端口&#xff0c;用于通过命令行模式或远程连接软件&#xff08;例如PuTTY、Xshell、SecureCRT等&#xff09;连接Linux实例。23TelnetTelnet端口&#xff0c;用于Telnet远程登…

【教学类-40-04】A4骰子纸模制作4.0(4.5CM嵌套+记录表带符号)

作品展示 背景需求 骰子3.0&#xff08;7字形&#xff09;存在问题&#xff1a;6.5骰子体积大大&#xff0c;不适合幼儿操作&#xff08;和幼儿手掌一样大&#xff0c;制作耗时&#xff0c;甩动费力&#xff09; 1.0版本&#xff1a;边缘折线多&#xff0c;幼儿剪起来费力。 …

【网络编程】传输层——TCP协议

文章目录 TCP协议TCP协议格式窗口大小六个标志位确认应答机制超时重传机制连接管理机制三次握手四次挥手 流量控制滑动窗口拥塞控制延迟应答捎带应答面向字节流粘包问题TCP异常情况TCP小结基于TCP的应用层协议TCP与UDP的对比 TCP相关实验CLOSE_WAIT状态实验TIME_WAIT状态实验TI…

动态规划(3)---Leetcode509.斐波那契数

题目 分析 很明显的动态规划&#xff0c;直接写出。之前都是用递归来写。 题解 class Solution {public int fib(int n) {if (n0) return 0;if (n1) return 1;int q0,p1,r0;for(int i2;i<n;i){rqp;int tmpp;pr;qtmp; }return r;}

Postgresql数据类型-时间类型

PostgreSQL对时间、日期数据类型的支持丰富而灵活&#xff0c;本节介绍PostgreSQL支持的时间、日期类型&#xff0c;及其操作符和常用函数。 PostgreSQL支持的时间、日期类型如表所示。 我们通过一个简单的例子理解这几个时间、日期数据类型&#xff0c;先来看看系统自带的now…

解决“找不到vcruntime140.dll,无法继续执行代码”错误的方法,以及解决步骤

给大家分享解决“找不到vcruntime140.dll,无法继续执行代码”错误的方法&#xff0c;以及解决步骤&#xff0c;来看看都有哪些可行性的办法解决“找不到vcruntime140.dll,无法继续执行代码”吧。 一.vcruntime140.dll的常见问题 vcruntime140.dll是Microsoft Visual Studio Re…

iis 部署 netcore 和vue 共用端口

常规情况下&#xff0c;vue 和api是分开的两个站点进行部署&#xff0c;若是要对外只有一个端口的话&#xff0c;采用以下梁总方式即可。 1.需要配置路由转发和代理开启&#xff08;vue 使用hisoty模式&#xff09; 参考链接.netCore vue&#xff08;history模式&#xff0…

如何批量下载iconfont图标库

如何批量下载iconfont中svg图 原文链接&#xff1a; https://gitee.com/veigarchen/iconfont-download 1、下载插件到本地 2、将解压的文件添加到浏览器扩展中 3、按需下载自己的图标

华为Auth-Http Serve任意文件读取

1.漏洞描述 华为Auth-Http Server 1.0任意文件读取&#xff0c;攻击者可通过该漏洞读取任意文件。 2.网络资产查找 FOFA&#xff1a;server”Huawei Auth-Http Server 1.0” 2、部分界面如下 3、Poc /umweb/shadow 4、Poc批量验证 id: huanwei-auth-http-server-filereadi…

2023中国互联网公司排行榜!

日前&#xff0c;中国互联网协会正式发布《中国互联网企业综合实力指数&#xff08;2023&#xff09;》报告&#xff0c;同时还发布了2023年中国互联网综合实力前百家企业榜单、2023年中国互联网成长型前二十家企业和数据安全服务前五家企业名单。 总体来看&#xff0c;我国互…

苹果Apple ID忘了或者咨询其他问题如何让苹果客服打电话给你

环境&#xff1a; iPhone11 Apple ID 问题描述&#xff1a; 苹果Apple ID忘了或者咨询其他问题如何让苹果客服打电话给你 上次公司苹果设备&#xff0c;忘了激活锁的账户密码要向苹果申请解锁&#xff0c;打了很长电话&#xff0c;平时语音超套餐了&#xff0c;想着让他们…

Qt 4.8.6 的下载与安装

Qt 4.8.6 的下载与安装 Qt 4.8.6 的下载与安装下载并解压 MinGW 4.8.2Qt4.8.6 库的安装Qt Creator 3.3.0 的安装配置 Qt Creator测试 Qt 4.8.6 的下载与安装 学习《Qt Creator快速入门》&#xff08;第3版&#xff09;&#xff0c;书里面要用 Qt:phonon&#xff0c;这个组件要…

yolov8模型训练、目标跟踪

一、准备条件 1.下载yolov8 https://github.com/ultralytics/ultralytics2.安装python https://www.python.org/ftp/python/3.8.0/python-3.8.0-amd64.exe3.安装依赖 进入ultralytics-main&#xff0c;执行&#xff1a; pip install -r requirements.txt pip install -U ul…

【Git】git的安装与使用教程

【Git】git的安装与使用教程 1.简介1.1.什么是Git1.2.Git与SVN的区别 二、安装Git三、注册Gitee帐号四、使用Git进行上传与下载代码五、使用Git代码冲突六、Git常用命令 1.简介 1.1.什么是Git Git是一个分布式版本控制系统&#xff0c;用于跟踪和管理项目代码的变更。它可以记…

c++day6

#include <iostream>using namespace std; class Animal { public:virtual void peform() 0; }; class Monekey:public Animal { public:void peform(){cout << "猴子黑桃A" << endl;} }; class Elepthant:public Animal {void peform(){cout &l…

软文推广中如何搭建媒体矩阵

媒体矩阵简单理解就是在不同的媒体平台上&#xff0c;根据运营目标和需求&#xff0c;建立起全面系统的媒体布局&#xff0c;进行多平台同步运营。接下来媒介盒子就来和大家聊聊&#xff0c;企业在软文推广过程中为什么需要搭建媒体矩阵&#xff0c;又该如何搭建媒体矩阵。 一、…

LeetCode_多源 BFS_中等_2258.逃离火灾

目录 1.题目2.思路3.代码实现&#xff08;Java&#xff09; 1.题目 给你一个下标从 0 开始大小为 m x n 的二维整数数组 grid &#xff0c;它表示一个网格图。每个格子为下面 3 个值之一&#xff1a; 0 表示草地。1 表示着火的格子。2 表示一座墙&#xff0c;你跟火都不能通过…

能源监测管理系统有哪些作用与效果?

随着全球能源的不断增加&#xff0c;能源的有限性与环境问题日益严重&#xff0c;用能管理企业需要一种高效的方法来管理能源与利用能源&#xff0c;因此能源监测管理系统成为了一种不可或缺的工具。 能源监测管理系统的重要性 1、实现节能减排的目标 通过系统&#xff0c;可…

Visual Studio2022安装教程【图文详解】(大一小白)编译软件

工欲善其事&#xff0c;必先利其器。想要学好编程&#xff0c;首先要把手中的工具利用好&#xff0c;今天小编教一下大家如何下载安装并使用史上最强大的编译器--Visual Studio&#x1f357; 一.Visual Studio下载及安装 https://visualstudio.microsoft.com/ 打开文件 点击.ex…

【计算机网络笔记】网络层服务模型——数据报网络

系列文章目录 什么是计算机网络&#xff1f; 什么是网络协议&#xff1f; 计算机网络的结构 数据交换之电路交换 数据交换之报文交换和分组交换 分组交换 vs 电路交换 计算机网络性能&#xff08;1&#xff09;——速率、带宽、延迟 计算机网络性能&#xff08;2&#xff09;…