数据结构实验——哈夫曼编码

article/2025/10/4 18:36:59

目录

问题描述

基本要求

问题分析

实验代码

运行结果

实验总结


问题描述

利用哈夫曼编码进行通信可以大大提高信道利用率,缩短信息传输时间,降低传输成本。但是,这要求在发送端通过一个编码系统对待传数据预先编码,在接收端将传来的数据进行译码(复原)。对于双工信道(即可以双向传输信息的信道),每端都需要一个完整的编/译码系统。试为这样的信息收发编写一个哈夫曼码的编/译码系统。

基本要求

(1)接收原始数据(电文):从终端输入电文(电文为一个字符串,假设仅由26个小写英文字母构成)。

(2)编码:利用已建好的哈夫曼树,对电文进行编码。

(3)打印编码规则:即字符与编码的一一对应关系。

(4)打印显示电文以及该电文对应的哈夫曼编码。

(5)接收原始数据(哈夫曼编码):从终端输入一串哈二进制哈夫曼编码(由

0和1构成)。

(6)译码:利用已建好的哈夫曼树对该二进制编码进行译码。

(7)打印译码内容:将译码结果显示在终端上。

问题分析

(一)算法设计思路:

(1)接收原始数据:从Huffm.txt读入字符及其对应权值,建立哈夫曼树。

字符

-

A

B

C

D

E

F

G

H

I

J

K

L

M

频度

186

64

13

22

32

103

21

15

47

57

1

5

32

20

字符

N

O

P

Q

R

S

T

U

V

W

X

Y

Z

频度

57

63

15

1

48

51

80

23

8

18

1

16

1

    

(2)编码:利用建好的哈夫曼树进行编码,存入HuffCode中,输入字符串,输出相应的密文。

(3)译码:利用已建好的哈夫曼树,将密文解码,输出对应明文。

(4)打印编码规则:字符与编码一一对应。

(二)使用模块及变量的说明

(1)typedef struct HNodeType:定义叶子结点。

(2)typedef struct HNodeType HFMTree[2*HUFFCODE-1]:建立储存哈夫曼树的数组。

(3)typedef struct HCodeType:定义储存编码的结点

(4)HCodeType HuffCode[HUFFCODE]:建立编码的数组

(5)void Creat_HuffMTree(HNodeType HFMTree[],int n):构造哈夫曼树

(6)void HaffmanCode(HNodeType HFMTree[], HCodeType HuffCode[],int n):哈夫曼编码过程,左分支是0,右分支是1

(7)void print_HuffCode(HCodeType HuffCode[]):打印编码规则

(8)void code_Huff(HCodeType HuffCode[],string s):编码过程,将字符串进行编码并输出对应二进制数

(9)void decode_Huff(string s, HNodeType HFMTree[], int n):译码过程,将二进制数使用哈夫曼树进行译码

实验代码

C++版

#include<iostream>
#include<fstream>
#include<string>
using namespace std;
#define HUFFCODE 27  //27个字符
#define MAXVALUE 10000 //构造哈夫曼树时使用//定义叶子结点
typedef struct {char data;int weight;int parent, lchild, rchild;
}HNodeType;
HNodeType HFMTree[2*HUFFCODE-1];//结构数组储存各字符编码
typedef struct {char data;    //每个结点储存字符int bit[HUFFCODE];   int start; 
}HCodeType;
HCodeType HuffCode[HUFFCODE];//储存编码的数组//构造哈夫曼树
void Creat_HuffMTree(HNodeType HFMTree[],int n) {  int m1, x1, m2, x2;  //x1,x2存储最小和次小权值,m1,m2存储其位置int i, j;for (int i = 0; i < 2 * n - 1; i++) {  //HFMTree初始化HFMTree[i].weight = 0;		HFMTree[i].parent = -1;HFMTree[i].lchild = -1;		HFMTree[i].rchild = -1;}HFMTree[0].data = '_'; HFMTree[0].weight = 186;//设置空格(改为_了)的权值ifstream myfile("Huffm.txt");for (int i = 1; i < n; i++) {	myfile >> HFMTree[i].data;myfile >> HFMTree[i].weight;}myfile.close();for (int i = 0; i < n - 1; i++) {  //构造哈夫曼树x1 = x2 = MAXVALUE;m1 = m2 = 0;for (int j = 0; j < n + i; j++) {  //找出根结点具有最小和次小权值的两棵树if (HFMTree[j].parent == -1 && HFMTree[j].weight < x1) {x2 = x1; m2 = m1;x1 = HFMTree[j].weight; m1 = j;}else if (HFMTree[j].parent == -1 && HFMTree[j].weight < x2) {x2 = HFMTree[j].weight; m2 = j;}}HFMTree[m1].parent = n + i; HFMTree[m2].parent = n + i;//合并两棵树HFMTree[n + i].weight = HFMTree[m1].weight + HFMTree[m2].weight;HFMTree[n + i].lchild = m1; HFMTree[n + i].rchild = m2;}	
}//哈夫曼编码过程,左分支是0,右分支是1 
void HaffmanCode(HNodeType HFMTree[], HCodeType HuffCode[],int n) {HCodeType cd;    //字符编码的缓冲变量int i, j, c, p;for (i = 0; i < n; i++) {  //求每个叶子结点的哈夫曼编码cd.start = n - 1;c = i;p = HFMTree[c].parent;cd.data = HFMTree[c].data;while (p != -1) {if (HFMTree[p].lchild == c) cd.bit[cd.start] = 0;else cd.bit[cd.start] = 1;cd.start--;c = p;p = HFMTree[c].parent;}for (j = cd.start + 1; j < n; j++) {  //保存求出的每个叶结点的哈夫曼编码和编码的起始位置HuffCode[i].bit[j] = cd.bit[j];}HuffCode[i].start = cd.start + 1;HuffCode[i].data = cd.data;}
}//打印编码规则
void print_HuffCode(HCodeType HuffCode[]) {for (int i = 0; i < HUFFCODE; i++) {cout << HuffCode[i].data<<"对应编码:";for (int j = HuffCode[i].start; j < HUFFCODE; j++) {cout << HuffCode[i].bit[j];}cout << endl;}
}//编码过程,将字符串进行编码并输出对应二进制数
void code_Huff(HCodeType HuffCode[],string s) {int i = 0;ofstream outfile("textfile.txt");while (s[i] != '\0') {for (int j = 0; j < HUFFCODE; j++) { //遍历HuffCodeif (s[i] == HuffCode[j].data) {for (int k = HuffCode[j].start; k < HUFFCODE; k++) {cout << HuffCode[j].bit[k];}i++;break;}}}cout << endl;
}//译码过程,将二进制数使用哈夫曼树进行译码
void decode_Huff(string s, HNodeType HFMTree[], int n) {int i = 0, j = 0, p = 2 * n - 2;char a[1000] = {};while (s[i] != '\0') {if (s[i] == '0') {p = HFMTree[p].lchild;}else if (s[i] == '1') {p = HFMTree[p].rchild;}                //判断p是否为叶子结点,是则将对应数据储存进aif (HFMTree[p].lchild == -1 && HFMTree[p].rchild == -1) {a[j] = HFMTree[p].data; j++;p = 2 * n - 2;}else if (s[i + 1] == '\0' && HFMTree[p].lchild != -1 && HFMTree[p].rchild != -1) {cout << "译码失败!" << endl;return;}i++;}int k = 0;while (a[k]!=0 ) cout << a[k++];cout << endl;
}int menu() {int a;cout << "请选择功能键:";cin >> a;if (a >= 0 && a <= 3) 	return a;else return -1;
}int main() {int a;string s1, s2;Creat_HuffMTree(HFMTree, HUFFCODE);HaffmanCode(HFMTree, HuffCode, HUFFCODE);cout << "********************" << endl;cout << "1.编码" << endl;cout << "2.译码" << endl;cout << "3.打印编码规则" << endl;cout << "0.退出" << endl;cout << "********************" << endl;a = menu();while (a != 0) {switch (a) {case 1:cout << "请输入要进行编码的明文:";cin >> s1;code_Huff(HuffCode, s1);    //进行编码a = menu();break;case 2:cout << "请输入要进行解码的密文:";cin >> s2;decode_Huff(s2, HFMTree, HUFFCODE);    //进行译码a = menu();break;case 3:cout << "编码规则为:" << endl;print_HuffCode(HuffCode);a = menu();break;case -1:cout << "请输入正确的功能键!" << endl;a = menu();break;}		}cout << "退出成功!" << endl;system("pause");return 0;
}

运行结果

 

实验总结

1、构造哈夫曼树时,从Huffm.txt读入字符及对应权值,需要使用fstream库。构造过程中数组下标没有处理好,导致出现各种问题。

2、译码过程用字符数组储存结果,若译码失败则不输出。这个过程最开始使用的是一个字符串变量储存,出现错误,程序无法运行,改用字符数组储存,并进行初始化,就解决了问题。


http://chatgpt.dhexx.cn/article/emjk9KOk.shtml

相关文章

数据结构实验C语言实现版

目录 数据结构实验——顺序表的基本操作 数据结构实验——单链表的基本操作 数据结构实验——顺序栈的建立及基本操作实现 数据结构实验——链队列的建立及基本操作实现 数据结构实验——赫夫曼树构造及赫夫曼编码的实现 数据结构实验——迪杰斯特拉算法求最短路径 数据结…

数据结构实验报告

数据结构与算法实验一&#xff08;顺序表的操作&#xff09; 一、实验目的 1&#xff0e;掌握线性表的顺序存储结构的表示和实现方法。 2&#xff0e;掌握顺序表基本操作的算法实现。 3&#xff0e;了解顺序表的应用。 二、实验内容 1&#xff0e;建立顺序表。 2&#xff0…

【数据结构】实验项目:顺序表,也就那么回事

目录 序 嗨&#xff0c;这里是狐狸~~ 简介 顺序表的结构定义&#xff1a; 声明顺序表类型变量&#xff1a; 实验内容&#xff1a; 实验说明 : 实验思路 1、 输入一组整型元素序列&#xff08;不少于10个&#xff09;&#xff0c;建立顺序表。 2&#xff0e; 在该顺…

数据结构(实验一)

第一次写报告&#xff0c;虽然有点简单&#xff0c;但还是要勉励自己再接再厉。加油 继续努力。 1.实验目的&#xff08;结出本次实验所涉及并要求掌握的知识点&#xff09; 1.掌握顺序表的存储结构形式及描述方法和基本运算的实现&#xff1b; 2.掌握用顺序表设计合理的数据…

数据结构实验

1.有序数组的插入 代码&#xff1a; bool Insert( List L, ElementType X ){//溢出if(L->LastMAXSIZE-1) return false;//插入在最后一位if(L->Data[L->Last] > X){L->Data[L->Last1]X;L->Last;return true;}int tp0;int find0;int tmp0;for(int i0;i &l…

网络传输大文件使用什么软件可以高速传输?

网络传输大文件使用什么软件可以高速传输&#xff1f;通过网络传输文件总是在速度上得不到很好的体现&#xff0c;更不用说是传输大文件了。本身支持大文件网络传输的工具就是不是很多&#xff0c;很多的传输工具对文件的大小都有所限制&#xff0c;要是想要找到一个高速传输大…

.mmap文件用什么软件可以打开?

1.下载MindManager专属打开它的软件 2。

什么是Saas软件?

人们常常会提及Saas&#xff08;萨斯&#xff09;软件&#xff0c;那么什么是Saas软件呢&#xff1f;首先大家通过百度可以看到百度百科的解释 相信大多数的伙伴们看了之后的感想就是一脸蒙圈&#xff0c;如果让自己给别人介绍什么是Saas软件还是记不住解释不清楚&#xff0c;那…

测试移动信号频率的软件,手机信号工作频段侦测软件

手机信号来源于基站发射的信号。但是常常会遇见的手机信号差&#xff0c;信号弱&#xff0c;上网速度慢等&#xff0c;都有可能是源于信号弱带来的。那么我们看见的手机上显示的信号弱&#xff0c;到底是什么信号弱&#xff1f;如何判别&#xff1f; 这里推荐一款APP软件&#…

杀毒软件可以查杀所有计算机病毒吗,杀毒软件可以查杀所有病毒吗

杀毒软件包括电脑杀毒软件和手机杀毒软件&#xff0c;那么杀毒软件可以查杀所有病毒吗&#xff1f;目前&#xff0c;做到所有病毒查杀还没有一家杀毒软件敢100%保证&#xff0c;因为电脑病毒也在日新月异的发展着&#xff0c;那是不是新病毒就查杀不了呢&#xff1f;也不是&…

可以测试电脑网络速度的软件,介绍4种有用的Internet Speed软件应用程序,用于测试网络速度软件...

当今社会将使用Internet&#xff0c;但是Internet的速度极大地影响了我们的工作和浏览. 在玩游戏和观看视频时测网速什么软件好&#xff0c;拥有一个良好的Internet甚至更为必要. 目前&#xff0c;我们可以使用Internet速度测试软件进行测试. 网络的速度和稳定性使您可以更好地…

什么软件可以测试鬼,PP助手新奇App推荐 《鬼魂探测器》能抓鬼?

最近&#xff0c;小伙伴们迷上了一款奇葩App&#xff0c;据说可以将潜伏在你周围的“阿飘”揪出来。这款软件就是《鬼魂探测器》&#xff0c;听起来是不是有点毛骨悚然&#xff0c;但又忍不住好奇心&#xff0c;通过PP助手下载一探究竟吧。 图1&#xff1a;PP助手(Win)2.0 只要…

测试电脑整机功耗软件,有什么好的测电脑整机功耗的软件吗?

很多人都说电脑的速度越快耗电量就越快&#xff0c;早期的486和现在的P4相比&#xff0c;那简直就是“节能电脑”了&#xff0c;那么想不想知道你的电脑到底有耗电量是多少呢&#xff1f;来试试Overclockulator吧&#xff0c;根据你的选择它可以估算出一台电脑的耗电量。 该软件…

有没有测试颜色的软件,用什么软件测试显示器色彩最准:色彩校正软件

用什么软件测试显示器色彩最准&#xff1a;1.iphone直接显示器校色&#xff0c;这个估计是最有效的方法。有的人可能用不惯iphone的界面&#xff0c;我经常用iphone来测试工程数据&#xff0c;因为iphone有自己的屏幕校色传感器&#xff0c;而iphone的屏幕比一般的显示器都要准…

java用什么软件_Java编程什么软件最好用?

原标题&#xff1a;Java编程什么软件最好用&#xff1f; “工欲善其事必先利其器”&#xff0c;想要学好Java编程开发&#xff0c;除了要有好的学习资源之外&#xff0c;还要有一套适合自己的Java编程软件&#xff0c;好的编程软件能极大提高你的学习和工作效率。那么&#xff…

kml用什么软件打开?

下载安装 bigemap GIS office软件&#xff08;免费就可以) 2、 安装好下载的bigemap软件&#xff0c;直接将kml kmz拖到软件里面就打开了&#xff0c;或者左上角文件打开 选择 kml/kmz 然后选择你的文件 打开记性了。 BIGEMAP支持所有文件格式的打开和保存&#xff0c;如…

可以测试英语发音的软件,检测英语发音的软件

目录 一、音标软件 ①.同求!!!和外国人多说说话。 ②.百度里打“朗酷口语”就可以了~~ 这 个软件可以的!俺也用~~~ 哈哈祝你好运~~。 ③.你好,你说的就跟复读机是一个道理。这种软件不过就是对于人的音频和关键点做了一个发音的匹配度测试,语音库会先前录好没一个单词的发…

测试显卡用什么软件最好,显卡测试用什么软件 怎么测试显卡性能

如果要精确的测试一块显卡的性能则需要一款专业的显卡测试软件,显卡测试用什么软件?像3dmark 11、built-in benchmark tool、gpu-z等软件都是相当优秀的显卡测试软件,另外的测试就是烤机了,可以利用furmark软件烤机测试显卡性能。今天小编就为大家介绍显卡测试的方法。 什么…

有什么软件可以直接拒接所有骚扰电话?3款App让你不再为骚扰电话烦恼

现在大部分智能手机都有自带的拦截功能&#xff0c;可以自动标记可疑的来电号码、对垃圾短信也能起到拦截作用。如果你的手机没有这种功能&#xff0c;也可以下载第三方安全软件进行拦截。 熊猫吃短信app&#xff1a;点击左侧链接下载 熊猫吃短信app是一款值得推荐的垃圾短信过…

什么软件专业测试电脑,测验电脑性能 用什么软件

方法/步骤 1.首先说说电脑的第一个检测&#xff1a;硬件检测&#xff0c;其核心是CPU和GPU(也就是处理器和显卡)。 2.为什么需要这款软件呢&#xff0c;其实在笔记本里这款软件用处不是特别大&#xff0c;因为笔记本配置其实相对很死板(但是硬件详细信息还是有用的&#xff0c;…