北邮数据结构实验3哈夫曼编码
实验三 哈夫曼编码
实验一离散信源及其信息测度
一、实验目的
1、理解信源编码的意义;
2、熟悉 MATLAB程序设计;
3、掌握哈夫曼编码的方法及计算机实现;
二、实验原理
通信的根本问题是如何将信源输出的信息在接收端的信宿精确或近似的复制出来。为了有效地复制信号,就通过对信源进行编码,使通信系统与信源的统计特性相匹配。
若接收端要求无失真地精确地复制信源输出的信息,这样的信源编码即为无失真编码。即使对于一个小的时间段内,连续信源输出的信息量也可以是无限大的,所以对其是无法实现无失真编码的;而离散信源输出的信息量却可以看成是有限的,所以只有离散信源才可能实现无失真编码。
凡是能载荷一定的信息量,且码字的平均长度最短,可分离的变长码的码字集合都可以称为最佳码。为此必须将概率大的信息符号编以短的码字,概率小的符号编以长的码字,使得平均码字长度最短。
变字长编码的最佳编码定理:在变字长码中,对于概率大的信息符号编以短字长的码;对于概率小的信息符号编以长字长的码。如果码字长度严格按照符号概率的大小顺序排列,则平均码字长度一定小于俺任何顺序排列方式得到的码字长度。
哈夫曼编码就是利用了这个定理,讲等长分组的信源符号,根据其概率分布采用不等长编码。概率大的分组,使用短的码字编码;概率小的分组,使用长的码字编码。哈夫曼编码把信源按概率大小顺序排列,并设法按逆次序分配码字的长度。在分配码字的长度时,首先将出现概率最小的两个符号相加,合成一个概率;第二步把这个合成的概率看成是一个新组合符号的概率,重复上述做法,直到最后只剩下两个符号的概率为止。完成以上概率相加顺序排列后,再反过来逐步向前进行编码。每一步有两个分支,各赋予一个二进制码,可以对概率大的编为0码,概率小的编为1码。反之亦然。
数据结构哈夫曼编码实验报告
数据结构哈夫曼编码实验报告
一、实验目的:
通过哈夫曼编、译码算法的实现,巩固二叉树及哈夫曼树相关知识的理解掌握,训练学生运用所学知识,解决实际问题的能力。
二、实验内容:
已知每一个字符出现的频率,构造哈夫曼树,并设计哈夫曼编码。
1、从终端读入字符集大小n,以及n个字符和n个权值,建立哈夫曼树。
2、打印每一个字符对应的哈夫曼编码。
3、对从终端读入的字符串进行编码,并显示编码结果。
4、对从终端读入的编码串进行译码,并显示译码结果。
三、实验方案设计:
(对基本数据类型定义要有注释说明,解决问题的算法思想描述要完整,算法结构和程序功能模块之间的逻辑调用关系要清晰,关键算法要有相应的流程图,对算法的时间复杂度要进行分析)
1、算法思想:
(1)构造两个结构体分别存储结点的字符及权值、哈夫曼编码值:
(2)读取前n个结点的字符及权值,建立哈夫曼树:
(3)根据哈夫曼树求出哈夫曼编码:
2、算法时间复杂度:
(1)建立哈夫曼树时进行n到1次合并,产生n到1个新结点,并选出两个权值最小的根结点:O(n²);
(2)根据哈夫曼树求出哈夫曼编码:O(n²)。
(3)读入电文,根据哈夫曼树译码:O(n)。
四、该程序的功能和运行结果:
(至少有三种不同的测试数据和相应的运行结果,充分体现该程序的鲁棒性)
1、输入字符A,B,C,D,E,F及其相应权值16、1
2、9、30、6、3。
2、输入字符F,E,N,G,H,U,I及其相应权值30、12、2
3、22、12、7、9。
3、输入字符A,B,C,D,E,F,G,H,I,G及其相应权值19、23、25、18、12、67、23、9、32、33。
数据结构大作业-哈夫曼编码实验报告
一.构造过程
①统计可知,字符串全长共59个字符,其中字符‘A’-‘F’的出现频数及对应概率(保留两位小数)如图所示:
②将每个字符出现概率作为权重,则对于上述给定的6个权值{25,15,14,20,17,9},依次构造6棵只有根节点的二叉树,共同构成森林F;
③在森林F中,选取权重最小和次小的两颗树,分别作为新二叉树的左子树、右子树,且该树根节点权值赋左右子树权值之和;
④从森林F中删除已选中的两棵子树,把新得到的二叉树加入F 中;
⑤重复③④,直到森林F中仅留下一棵树时,得到最终的哈夫曼树HF如图所示:
⑥对上述哈夫曼树,将其树中的每个左分支赋0、右分支赋1,则从根结点开始到叶子结点,各分支路径分别得到对应的二进制串,即为给定的每个字符的哈夫曼编码。
二、代码实现
源代码如下:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define N 6 //指定的编码字符数
#define M (2 * N - 1) //HT结点数
#define MAXWEIGHT 100
typedef struct { //哈夫曼树的存储表示
int weight;
int parent, lchild, rchild;
}HTNode;
typedef HTNode HuffmanTree[M + 1];
typedef char* HuffmanCode[N + 1]; //哈夫曼编码表
数据结构 哈夫曼编码实验报告
数据结构哈夫曼编码实验报告
数据结构哈夫曼编码实验报告
1. 实验目的
本实验旨在通过实践理解哈夫曼编码的原理和实现方法,加深
对数据结构中树的理解,并掌握使用Python编写哈夫曼编码的能力。
2. 实验原理
哈夫曼编码是一种用于无损数据压缩的算法,通过根据字符出
现的频率构建一棵哈夫曼树,并根据哈夫曼树对应的编码。根据哈
夫曼树的特性,频率较低的字符具有较长的编码,而频率较高的字
符具有较短的编码,从而实现了对数据的有效压缩。
实现哈夫曼编码的主要步骤如下:
1. 统计输入文本中每个字符的频率。
2. 根据字符频率构建哈夫曼树,其中树的叶子节点代表字符,
内部节点代表字符频率的累加。
3. 遍历哈夫曼树,根据左右子树的关系对应的哈夫曼编码。
4. 使用的哈夫曼编码对输入文本进行编码。
5. 将编码后的二进制数据保存到文件,同时保存用于解码的哈
夫曼树结构。
6. 对编码后的文件进行解码,还原原始文本。
3. 实验过程
3.1 统计字符频率
首先,我们需要统计输入文本中每个字符出现的频率。可以使用Python中的字典数据结构来记录字符频率。遍历输入文本的每个字符,将字符添加到字典中,并递增相应字符频率的计数。
```python
def count_frequency(text):
frequency = {}
for char in text:
if char in frequency:
frequency[char] += 1
else:
frequency[char] = 1
return frequency
```
3.2 构建哈夫曼树
数据结构实验——赫夫曼编码
实习三二叉树应用
一、实验目的:
熟悉二叉树的存储结构,二叉树的有关的操作。
二、实验内容及要求:
哈夫曼编/译码器
[问题描述]
利用哈夫曼编码进行通信可以大大提高信道利用率,这要求在发送端通过一个编码系统
对待传输预先编码,在接收端将传来的数据进行译码。对于双工通道,每端都需要一个完整
的编/译码系统。
[基本要求]
试为这样的信息收发站写一个哈夫曼码的编/译码系统。
[实现提示]
构造哈夫曼树的算法实现:
假设哈夫曼树采用双亲孩子表示法存储,并增加权值域,构造哈夫曼树的叶子结点(树
木的权)有N个,合并次数为N—1次,则森林中总共有2N—1棵树,(包含合并后删除的)。
存储结构描述为:
const int n=maxn //maxn表示叶子数目
const int m=2*n-1 //m为森林中树的棵数
class tree
{
float weight; //权值
int parent; //双亲
int lch, rch; //左,右孩子
}
tree hftree[m+1]; //规定从第一个元素hftree[1]开始使用数组元素,故定义长
度为m+1而不为m
结构类型:
typedef struct
{
char data;
int weight;
int parent;
int lchild;
int rchild;
}huffnode;
typedef struct
{
char cd[MAX];
int start;
}huffcode;
主程序
int main()
{
初始化:输入字符代码以及权值。
编制哈夫曼码:根据权值建立二叉树, 输出相应的根节点到叶结点的路径,便是哈夫曼编码。
数据结构哈夫曼编码实验报告
数据结构哈夫曼编码实验报告
数据结构哈夫曼编码实验报告
一、实验背景
1:引言
在日常生活中,信息传输已经成为了一个非常重要的环节。通过对信息进行编码,可以有效地减少信息传输的开销和存储空间。哈夫曼编码是一种常见的无损数据压缩方法,广泛应用于图像、音频和视频等领域。本实验旨在通过实现哈夫曼编码算法,深入理解其工作原理,并对其性能进行评估。
2:实验目的
本实验旨在:
a:了解哈夫曼编码算法的基本原理;
b:实现哈夫曼编码算法,并将其应用于对文本进行压缩;
c:评估哈夫曼编码算法在不同文本数据上的性能。
二、实验内容
1:哈夫曼编码原理介绍
2:哈夫曼编码的实现思路
a:构建哈夫曼树
b:哈夫曼编码表
c:对文本进行编码和解码
3:实验环境介绍
a:硬件环境
b:软件环境
4:实验步骤详解
a:构建哈夫曼树的实现方法
b:哈夫曼编码表的实现方法
c:文本编码和解码的实现方法5:实验数据与结果分析
a:不同文本数据的压缩结果对比 b:压缩性能的评估指标
6:实验心得与建议
a:实验过程中遇到的问题
b:改进与优化方向
三、实验结果与分析
1:实验数据
a:不同文本数据的大小与内容
b:压缩率等性能指标数据
2:实验结果分析
a:不同文本数据对压缩效果的影响
b:压缩率与文本数据的关系
c:哈夫曼编码的运行时间分析
四、结论
根据实验结果和分析,可以得出以下结论:
1:哈夫曼编码算法能够有效地减少文本数据的存储空间。
2:不同文本数据的压缩率存在差异,与文本的特性有关。
3:哈夫曼编码算法的运行时间与文本数据的长度成正比关系。附件:
1:实验源代码
2:实验数据和结果
数据结构实验十三
数据结构实验十三
数据结构实验十三:实现哈夫曼编码
哈夫曼编码是一种用于数据压缩的算法,通过将出现频率较高的字符用较短的编码表示,从而实现对数据的高效压缩。本实验旨在通过实现哈夫曼编码算法,加深对数据结构中二叉树的理解,并掌握哈夫曼编码的原理和实现方法。
一、实验要求:
1. 实现哈夫曼编码的算法;
2. 输入一段文本,统计各个字符的出现频率;
3. 根据字符频率构建哈夫曼树;
4. 根据哈夫曼树生成字符的编码表;
5. 将原始文本使用哈夫曼编码进行压缩;
6. 将压缩后的二进制数据进行解码,还原为原始文本。
二、实验步骤:
1. 首先,读取待压缩的文本内容,并统计每个字符的出现频率。可以使用一个哈希表来存储字符及其频率的对应关系。
示例输入:Hello, World!
字符频率统计结果:
H: 1
e: 1
l: 3
,: 1
空格: 1
W: 1
r: 1
d: 1
!: 1
2. 根据字符频率构建哈夫曼树。可以使用最小堆来实现优先队列,将字符频率作为优先级,构建哈夫曼树的过程即为不断合并两个频率最小的节点,直到只剩下一个根节点。
示例哈夫曼树构建过程:
步骤1:将字符频率作为优先级,构建最小堆。
步骤2:从最小堆中取出频率最小的两个节点,合并为一个新节点,频率为两个节点频率之和。
步骤3:将新节点插入最小堆中。
步骤4:重复步骤2和步骤3,直到最小堆中只剩下一个节点,即为哈夫曼树的根节点。
3. 根据哈夫曼树生成字符的编码表。遍历哈夫曼树,记录从根节点到每个叶子节点的路径,路径上的左右分支分别对应编码中的0和1。
示例编码表:
H: 000
数据结构 哈夫曼编码实验报告
数据结构哈夫曼编码实验报告
正文:
1:引言
本实验旨在学习和实现哈夫曼编码算法,通过对文本文件进行
压缩和解压缩操作,以提高数据传输和存储效率。本报告详细记录
了实验的设计、实现过程、实验结果以及相应的分析和讨论。
2:算法原理
2.1 哈夫曼编码原理
哈夫曼编码是一种变长编码的方式,根据字符出现的频率来构
建不同长度的编码,以实现高效地压缩数据。其主要步骤包括构建
哈夫曼树、哈夫曼编码表和对文本进行编码。
2.2 构建哈夫曼树
构建哈夫曼树的过程首先需要统计文本中每个字符出现的频率,然后根据频率构建最小堆,将频率较小的字符作为叶子节点,频率
较大的字符作为父节点,并不断合并节点,直到构建完整的哈夫曼树。
2.3 哈夫曼编码表
根据构建好的哈夫曼树,可以通过遍历树的路径来每个字符对应的哈夫曼编码,其中左分支表示0,右分支表示1,通过遍历整个树的路径可以得到每个字符的哈夫曼编码。
2.4 对文本进行编码和解码
根据的哈夫曼编码表,可以将文本中的每个字符进行编码,将编码后的二进制数据写入到文件中。对于解码操作,则是根据哈夫曼编码表和编码后的二进制数据,通过遍历哈夫曼树来还原出原始的文本。
3:实验设计
3.1 实验环境
本实验在操作系统为Windows的计算机上使用C++语言进行编程实现。
3.2 实验步骤
(1) 读取待压缩的文本文件。
(2) 统计文本中每个字符的频率。
(3) 构建哈夫曼树。
(4) 哈夫曼编码表。
(5) 将原始文本编码为二进制文件。
(6) 解码二进制文件,还原出原始文本。
4:实验实现
4.1 数据结构
(1) 节点结构体:包括字符和频率两个成员。
北邮数据结构实验—Huffman编码解码器
数据结构
实
验
报
告
实验名称:____Huffman编码/解码器_____学生姓名:__________________
班级:__________________
班内序号:__________________
学号:__________________
日期:___________________
1.实验要求
利用二叉树结构实现哈夫曼编/解码器。
基本要求:
1.初始化(Init):能够对输入的任意长度的字符串s进行统计,统计每个字符的频度,并建立哈夫曼树
2.建立编码表(CreateTable):利用已经建好的哈夫曼树进行编码,并将每个字符的编码输出。
3.编码(Encoding):根据编码表对输入的字符串进行编码,并将编码后的字符串输出。
4.译码(Decoding):利用已经建好的哈夫曼树对编码后的字符串进行译码,并输出译码结果。
5.计算输入的字符串编码前和编码后的长度,并进行分析,讨论赫夫曼编码的压缩效果。
2. 程序分析
2.1 存储结构
静态三叉链表
2.2 程序流程 (或程序结构、或类关系图等表明程序构成的内容,一般为流程图等)
2.2.1.流程图
2.2.1.伪代码
1.输入进行编码的字符串
2.遍历字符串,并为叶子节点权重赋值
3.依次对各字符进行哈弗曼编码,自下往上,若是双亲节点左孩子则编码前插入‘0’,若是双亲节点右孩子则编码钱插入‘1’。
4.显示各字符的哈弗曼编码。
5.对字符串进行编码,挨个遍历字符,找到相应的编码,复制到总的编码里,最后输出字符串的编码。
6.对字符串的哈弗曼码进行译码。自上往下,若是‘0’,则递归到左孩子,若是‘1’,则递归到右孩子,知道叶子节点,输出该叶子节点代表字符,再继续遍历。
北邮-数据结构-哈夫曼树报告Word版
数据结构
实
验
报
告
实验名称:哈夫曼树
学生姓名:袁普
班级:2013211125班
班内序号:14号
学号:2013210681
日期:2014年12月
实验目的和内容
利用二叉树结构实现哈夫曼编/解码器。
基本要求:
1、初始化(Init):能够对输入的任意长度的字符串 s进行统计,统计每个
字符的频度,
并建立哈夫曼树
2、建立编码表(CreateTable):利用已经建好的哈夫曼树进行编码,并将每
个字符的编码输出。
3、编码(Encoding):根据编码表对输入的字符串进行编码,并将编码后的
字符串输
出。
4、译码(Decoding):利用已经建好的哈夫曼树对编码后的字符串进行译码,
并输出
译码结果。
5、打印(Print):以直观的方式打印哈夫曼树(选作)
6、计算输入的字符串编码前和编码后的长度,并进行分析,讨论赫夫曼编
码的压
缩效果。
7、可采用二进制编码方式(选作)
测试数据:
I love data Structure, I love Computer。I will try my best to study
data Structure.
提示:
1、用户界面可以设计为“菜单”方式:能够进行交互。
2、根据输入的字符串中每个字符出现的次数统计频度,对没有出现的字符一
律不用编码
2. 程序分析
2.1 存储结构
用struct结构类型来实现存储
树的结点类型
struct HNode
{
int weight; //权值
int parent; //父节点
int lchild; //左孩子
int rchild; //右孩子
};
struct HCode //实现编码的结构类型
北邮信通院数据结构实验报告三哈夫曼编码器
数据结构实验报告
实验名称:实验三树——哈夫曼编/解码器
学生姓名:
班级:
班内序号:
学号:
日期:2014年12月11日
1.实验要求
利用二叉树结构实现赫夫曼编/解码器。
基本要求:
1、初始化(Init):能够对输入的任意长度的字符串s进行统计,统计每个
字符的频度,并建立赫夫曼树
2、建立编码表(CreateTable):利用已经建好的赫夫曼树进行编码,并将
每个字符的编码输出。
3、编码(Encoding):根据编码表对输入的字符串进行编码,并将编码后
的字符串输出。
4、译码(Decoding):利用已经建好的赫夫曼树对编码后的字符串进行译
码,并输出译码结果。
5、打印(Print):以直观的方式打印赫夫曼树(选作)
6、计算输入的字符串编码前和编码后的长度,并进行分析,讨论赫夫
曼编码的压缩效果。
测试数据:
I love data Structure, I love Computer。I will try my best to study data Structure.
提示:
1、用户界面可以设计为“菜单”方式:能够进行交互。
2、根据输入的字符串中每个字符出现的次数统计频度,对没有出现的
字符一律不用编码。
2. 程序分析
2.1 存储结构
Huffman树
给定一组具有确定权值的叶子结点,可以构造出不同的二叉树,其中带权路径长度最小的二叉树称为Huffman树,也叫做最优二叉树。
weight lchild rchild parent 2-1-1-1
5-1-1-1
6-1-1-1
7-1-1-1
9-1-1-1
weight lchild rchild parent
北邮数据结构实验报告三题目2-哈夫曼树
1
1.实验要求
利用二叉树结构实现哈夫曼编/ 解码器
(1). 初始化:能够对输入的任意长度的字符串s 进行统计,统计每个字符的频度,并建立哈夫曼树。
(2). 建立编码表:利用已经建好的哈夫曼树进行编码,并将每个字符的编码输出。
(3). 编码:根据编码表对输入的字符串进行编码,并将编码后的字符串输出。
(4). 译码:利用已经建好的哈夫曼树对编码后的字符串进行译码,并输出译码结果。
(5). 打印:以直观的方式打印哈夫曼树。
(6). 计算输入的字符串编码前和编码后的长度,并进行分析,讨论哈夫曼编码的压缩效果。
(7). 用户界面可以设计成“菜单”方式,能进行交互,根据输入的字符串中每个字符出现的次数统计频度,对没有出现的字符一律不用编码。
2.程序分析
2.1存储结构
二叉树:示意图:root
2.2
1
{2.3 关键算法分析
1. 定义哈夫曼树的模板类#include <iostream>
#include <string.h> using namespace std; struct
LNode {
char ch;
int weight;
char code[20];
LNode* next; };
struct TNode
{
int weight; //
int Lchild; //
int Rchild; //
int Parent; // };
class Huffman 结点权值
左孩子指针
右孩子指针
双亲指针
// 链表的节点, 用来统计字符频率,并编码
// 字符
// 权值
// 字符编码
// 指向下一个节点
数据结构哈夫曼编码实验报告
数据结构哈夫曼编码实验报告
【正文】
1.实验目的
本实验旨在研究哈夫曼编码的原理和实现方法,通过实验验证哈夫曼编码在数据压缩中的有效性,并分析其应用场景和优缺点。
2.实验原理
2.1 哈夫曼编码
哈夫曼编码是一种无损数据压缩算法,通过根据字符出现的频率构建一颗哈夫曼树,将频率较高的字符用较短的编码表示,频率较低的字符用较长的编码表示。哈夫曼编码的编码表是唯一的,且能够实现前缀编码,即一个编码不是另一个编码的前缀。
2.2 构建哈夫曼树
构建哈夫曼树的过程如下:
1) 将每个字符及其频率作为一个节点,构建一个节点集合。
2) 每次从节点集合中选择出现频率最低的两个节点,构建一个新节点,并将这两个节点从集合中删除。
3) 将新节点加入节点集合。
4) 重复以上步骤,直到节点集合中只有一个节点,这个节点就是哈夫曼树的根节点。
2.3 编码过程
根据哈夫曼树,对每个字符进行编码:
1) 从根节点开始,根据左子树为0,右子树为1的规则,将编码依次加入编码表。
2) 对于每个字符,根据编码表获取其编码。
3) 将编码存储起来,得到最终的编码序列。
3.实验步骤
3.1 数据读取与统计
从输入文件中读取字符序列,并统计各个字符的频率。
3.2 构建哈夫曼树
根据字符频率构建哈夫曼树。
3.3 构建编码表
根据哈夫曼树,构建每个字符的编码表。
3.4 进行编码
根据编码表,对输入的字符序列进行编码。
3.5 进行解码
根据哈夫曼树,对编码后的序列进行解码。
4.实验结果与分析
4.1 压缩率分析
计算原始数据和压缩后数据的比值,分析压缩率。
4.2 编码效率分析
实验三 哈夫曼编码
实验一离散信源及其信息测度
一、实验目的
1、理解信源编码的意义;
2、熟悉 MATLAB程序设计;
3、掌握哈夫曼编码的方法及计算机实现;
二、实验原理
通信的根本问题是如何将信源输出的信息在接收端的信宿精确或近似的复制出来。为了有效地复制信号,就通过对信源进行编码,使通信系统与信源的统计特性相匹配。
若接收端要求无失真地精确地复制信源输出的信息,这样的信源编码即为无失真编码。即使对于一个小的时间段内,连续信源输出的信息量也可以是无限大的,所以对其是无法实现无失真编码的;而离散信源输出的信息量却可以看成是有限的,所以只有离散信源才可能实现无失真编码。
凡是能载荷一定的信息量,且码字的平均长度最短,可分离的变长码的码字集合都可以称为最佳码。为此必须将概率大的信息符号编以短的码字,概率小的符号编以长的码字,使得平均码字长度最短。
变字长编码的最佳编码定理:在变字长码中,对于概率大的信息符号编以短字长的码;对于概率小的信息符号编以长字长的码。如果码字长度严格按照符号概率的大小顺序排列,则平均码字长度一定小于俺任何顺序排列方式得到的码字长度。
哈夫曼编码就是利用了这个定理,讲等长分组的信源符号,根据其概率分布采用不等长编码。概率大的分组,使用短的码字编码;概率小的分组,使用长的码字编码。哈夫曼编码把信源按概率大小顺序排列,并设法按逆次序分配码字的长度。在分配码字的长度时,首先将出现概率最小的两个符号相加,合成一个概率;第二步把这个合成的概率看成是一个新组合符号的概率,重复上述做法,直到最后只剩下两个符号的概率为止。完成以上概率相加顺序排列后,再反过来逐步向前进行编码。每一步有两个分支,各赋予一个二进制码,可以对概率大的编为0码,概率小的编为1码。反之亦然。
数据结构实验三题目二_哈夫曼树
2008级数据结构实验报告
实验名称:实验三树
学生姓名:
班级:
班内序号:
学号:
日期: 20013年11月26日
1.实验要求
实验目的
通过选择下面两个题目之一进行实现,掌握如下内容:
掌握二叉树基本操作的实现方法
了解赫夫曼树的思想和相关概念
学习使用二叉树解决实际问题的能力
实验内容
利用二叉树结构实现赫夫曼编/解码器。
基本要求:
1.初始化(Init):能够对输入的任意长度的字符串s进行统计,统计每个字符的频度,并
建立赫夫曼树
2.建立编码表(CreateTable):利用已经建好的赫夫曼树进行编码,并将每个字符的编码
输出。
3.编码(Encoding):根据编码表对输入的字符串进行编码,并将编码后的字符串输出。
4.译码(Decoding):利用已经建好的赫夫曼树对编码后的字符串进行译码,并输出译码结
果。
5.打印(Print):以直观的方式打印赫夫曼树(选作)
6.计算输入的字符串编码前和编码后的长度,并进行分析,讨论赫夫曼编码的压缩效果。
2. 程序分析
哈夫曼树结点的储存结构除了二叉树所有的双亲域parents,左子树域lchild,右子树域rchild。还需要有字符域word,权重域weight,编码域code。其中由于编码是一串由0和1组成的字符串,所以code是一个字符数组。
进行哈夫曼编码首先要对用户输入的信息进行统计,将每个字符作为哈夫曼树的叶子结点。统计每个字符出现的次数(频度)作为叶子的权重,统计次数可以根据每个字符不同的ASCII 码。并根据叶子结点的权重建立一个哈夫曼树。
建立每个叶子的编码从根结点开始,规定通往左子树路径记为0,通往右子树路径记为 1.由于编码要求从根结点开始,所以需要前序遍历哈夫曼树,故编码过程是以前序遍历二叉树
数据结构 哈夫曼编码实验报告
数据结构哈夫曼编码实验报告
数据结构实验报告
----------
1-实验目的
----------
本实验的目的是通过实现哈夫曼编码算法,加深对数据结构中树和堆的理解,以及掌握相关的编程技巧。
2-实验内容
----------
2-1 算法简介
----------
哈夫曼编码是一种无损压缩算法,通过根据字符出现的频率构建一颗二叉树,并将出现频率较高的字符编码为较短的二进制串,进而实现压缩的目的。在本实验中,我们需要实现以下功能:
●构建哈夫曼树
●字符编码表
●对给定的字符串进行编码
●对给定的二进制串进行解码
●实现压缩和解压缩功能
2-2 数据结构
----------
在实现哈夫曼编码算法时,我们需要使用以下数据结构:●链表:用于存储字符出现的频率及对应的字符
●堆:用于构建哈夫曼树
●树:用于存储哈夫曼编码树
●散列表或映射:用于存储字符的编码
2-3 算法步骤
----------
1-统计字符的出现频率,并构建频率链表
2-根据频率链表构建哈夫曼树
3-字符的编码表
4-对给定的字符串进行编码
5-对给定的二进制串进行解码
6-实现压缩和解压缩功能
3-实验实现
----------
3-1 数据结构的设计
----------
在本实验中,我们将使用以下数据结构:
●链表节点结构体:用于存储字符和频率
●链表结构体:用于存储链表节点的头指针
●堆节点结构体:用于存储字符和频率,并维护堆的结构
●堆结构体:用于存储堆的根节点
●树节点结构体:用于存储字符和编码,并维护哈夫曼树的结构
●树结构体:用于存储哈夫曼树的根节点
●散列表结构体:用于存储字符和对应的编码
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
数据结构实验报告
实验名称:实验3——哈夫曼编码
学生姓名:
班级:
班内序号:
学号:
日期:2013年11月24日
1.实验要求
利用二叉树结构实现赫夫曼编/解码器。
基本要求:
1、初始化(Init):能够对输入的任意长度的字符串s进行统计,统计每个
字符的频度,并建立赫夫曼树
2、建立编码表(CreateTable):利用已经建好的赫夫曼树进行编码,并将每
个字符的编码输出。
3、编码(Encoding):根据编码表对输入的字符串进行编码,并将编码后的
字符串输出。
4、译码(Decoding):利用已经建好的赫夫曼树对编码后的字符串进行译
码,并输出译码结果。
5、打印(Print):以直观的方式打印赫夫曼树(选作)
6、计算输入的字符串编码前和编码后的长度,并进行分析,讨论赫夫曼
编码的压缩效果。
2. 程序分析
2.1存储结构:
struct HNode
{
char c;//存字符内容
int weight;
int lchild, rchild, parent;
};
struct HCode
{
char data;
char code[100];
}; //字符及其编码结构
class Huffman
{
private:
HNode* huffTree; //Huffman树
HCode* HCodeTable; //Huffman编码表
public:
Huffman(void);
void CreateHTree(int a[], int n); //创建huffman树
void CreateCodeTable(char b[], int n); //创建编码表
void Encode(char *s, string *d); //编码
void Decode(char *s, char *d); //解码
void differ(char *,int n);
char str2[100];//数组中不同的字符组成的串
int dif;//str2[]的大小
~Huffman(void);
};
结点结构为如下所示:
三叉树的节点结构:
struct HNode//哈夫曼树结点的结构体
{ int weight;//结点权值
int parent;//双亲指针
int lchild;//左孩子指针
int rchild;//右孩子指针
char data;//字符
};
示意图为:
int weight int parent int lchild int rchild Char c 编码表节点结构:
struct HCode//编码表结构体
{
char data;//字符
char code[100];//编码内容
};
示意图为:
基本结构体记录字符和出现次数:
struct node
{
int num;
char data;
};
示意图为:
2.关键算法分析
(1).初始化:
伪代码:
1.输入需要编译的文本内容
2.将输入的内容保存到数组str1中
3.统计出现的字符数目,并且保存到变量count中
4.统计出现的不同的字符,存到str2中,将str2的大小存到dif中
时间复杂度O(n!)
(2).创建哈夫曼树
算法伪代码:
1.创建一个长度为2*n-1的三叉链表
2.将存储字符及其权值的链表中的字符逐个写入三叉链表的前n个结点的data域,并将对
应结点的孩子域和双亲域赋为空
3.从三叉链表的第n个结点开始,
3.1从存储字符及其权值的链表中取出两个权值最小的结点x,y,记录其
下标x,y。
3.2将下标为x和y的哈夫曼树的结点的双亲设置为第i个结点
3.3将下标为x的结点设置为i结点的左孩子,将下标为y的结点设置为
i结点的右孩子,i结点的权值为x结点的权值加上y结点的权值,i
结点的双亲设置为空
4.根据哈夫曼树创建编码表
时间复杂度O(n)
(3).创建编码表
算法伪代码:
1.初始化编码表
2.初始化一个指针,从链表的头结点开始,遍历整个链表
2.1 将链表中指针当前所指的结点包含的字符写入编码表中
2.2 得到该结点对应的哈夫曼树的叶子结点及其双亲
2.3 如果哈夫曼树只有一个叶子结点,将其字符对应编码设置为0
2.4 如果不止一个叶子结点,从当前叶子结点开始判断
2.4.1 如果当前叶子结点是其双亲的左孩子,则其对应的编码为0,否则为1
2.4.2 child指针指向叶子结点的双亲,parent指针指向child指针的双亲,重复2.4.1的操作
2.5 将已完成的编码倒序
2.6 取得链表中的下一个字符
3.输出编码表
时间复杂度O(n)
(4)选择两个最小权值的函数
算法伪代码:
1.从下标为i=0的开始遍历。前两次将x,y赋值为序号最小的两个结点的地址序
号。
2.开始进行比较:进行如下分类
对于任何不存在父节点的结点:
若x权值<=y权值
(1)且i权值>=y权值,则无疑i权值最大,为输出x、y为权值较小的两个故而x,y值不便;
(2)其余情况皆为x、i的权值是较小的两个,令y赋值为i,则保证x、y权值是最小的两个。
若y权值<=x权值
(1)且i权值>=x权值,则i权值是最大,x、y不变。
(2)其余情况皆为i、y权值最小,令x赋值为i,保证x、y序号结点的权值最小
3.完成如上循环,直至i=k则推出循环,第k个结点在树的位置已经确定
时间复杂度O(n)
(5). 将字符串倒序的函数(void HuffmanTree::Reverse(char *pch))
算法伪代码:
1.得到字符串的长度
2.初始化两个记录下标的变量,一个为字符串开头字符所在的下标i,另一个为字符串结尾字符所在的下标j
3.将下标为i和j的字符交换
4.i++,j - -
时间复杂度O(n)
(6).编码函数
算法伪代码:
1. 从开头的字符开始,逐一对a中的字符进行编码
2. 在编码表中查找与当前字符对应的字符
3.如果找到了与当前字符对应的编码表中的字符,将其编码追加到解码串的末
尾。