哈工大数据结构大作业——哈夫曼树生成、编码、遍历

合集下载

数据结构哈夫曼编码实验报告

数据结构哈夫曼编码实验报告

数据结构哈夫曼编码实验报告

一、实验目的:

通过哈夫曼编、译码算法的实现,巩固二叉树及哈夫曼树相关知识的理解掌握,训练学生运用所学知识,解决实际问题的能力。

二、实验内容:

已知每一个字符出现的频率,构造哈夫曼树,并设计哈夫曼编码。

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 构建哈夫曼树

哈夫曼树和哈夫曼编码(数据结构程序设计)

哈夫曼树和哈夫曼编码(数据结构程序设计)

课程设计

(数据结构)

哈夫曼树和哈夫曼编码

二○○九年六月二十六日课程设计任务书及成绩评定

课题名称表达式求值哈夫曼树和哈夫曼编码

Ⅰ、题目的目的和要求:

巩固和加深对数据结构的理解,通过上机实验、调试程序,加深对课本知识的理解,最终使学生能够熟练应用数据结构的知识写程序。

(1)通过本课程的学习,能熟练掌握几种基本数据结构的基本操作。

(2)能针对给定题目,选择相应的数据结构,分析并设计算法,进而给出问题的正确求解过程并编写代码实现。

Ⅱ、设计进度及完成情况

Ⅲ、主要参考文献及资料

[1] 严蔚敏数据结构(C语言版)清华大学出版社 1999

[2] 严蔚敏数据结构题集(C语言版)清华大学出版社 1999

[3] 谭浩强 C语言程序设计清华大学出版社

[4] 与所用编程环境相配套的C语言或C++相关的资料

Ⅳ、成绩评定:

设计成绩:(教师填写)

指导老师:(签字)

二○○九年六月二十六日

目录

第一章概述 (1)

第二章系统分析 (2)

第三章概要设计 (3)

第四章详细设计及实现代码 (8)

第五章调试过程中的问题及系统测试情况 (12)

第六章结束语 (13)

参考文献 (13)

第一章概述

课程设计是实践性教学中的一个重要环节,它以某一课程为基础,可以涉及和课程相关的各个方面,是一门独立于课程之外的特殊课程。课程设计是让同学们对所学的课程更全面的学习和应用,理解和掌握课程的相关知识。《数据结构》是一门重要的专业基础课,是计算机理论和应用的核心基础课程。

数据结构课程设计,要求学生在数据结构的逻辑特性和物理表示、数据结构的选择和应用、算法的设计及其实现等方面,加深对课程基本内容的理解。同时,在程序设计方法以及上机操作等基本技能和科学作风方面受到比较系统和严格的训练。

数据结构 哈夫曼编码实验报告

数据结构 哈夫曼编码实验报告

数据结构哈夫曼编码实验报告

正文:

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) 节点结构体:包括字符和频率两个成员。

数据结构哈夫曼树实验报告

数据结构哈夫曼树实验报告

数据结构哈夫曼树实验报告

一、实验内容

本次实验的主要内容是哈夫曼树的创建和编码解码。

二、实验目的

1. 理解并掌握哈夫曼树的创建过程;

2. 理解并掌握哈夫曼编码的原理及其实现方法;

3. 掌握哈夫曼树的基本操作,如求哈夫曼编码和哈夫曼解码等;

4. 学习如何组织程序结构,运用C++语言实现哈夫曼编码和解码。

三、实验原理

哈夫曼树的创建:

哈夫曼树的创建过程就是一个不断合并权值最小的两个叶节点的过程。具体步骤如下:

1. 将所有节点加入一个无序的优先队列里;

2. 不断地选出两个权值最小的节点,并将它们合并成为一个节点,其权值为这两个节点的权值之和;

3. 将新的节点插入到队列中,并继续执行步骤2,直到队列中只剩下一棵树,这就是哈夫曼树。

哈夫曼编码:

哈夫曼编码是一种无损压缩编码方式,它根据字符出现的频率来构建编码表,并通过编码表将字符转换成二进制位的字符串。具体实现方法如下:

1. 统计每个字符在文本中出现的频率,用一个数组记录下来;

2. 根据字符出现的频率创建哈夫曼树;

3. 从根节点开始遍历哈夫曼树,给左分支打上0的标记,给右分支打上1的标记。遍历每个叶节点,将对应的字符及其对应的编码存储在一个映射表中;

4. 遍历文本中的每个字符,查找其对应的编码表,并将编码字符串拼接起来,形成一个完整的编码字符串。

哈夫曼解码就是将编码字符串还原为原始文本的过程。具体实现方法如下:

1. 从根节点开始遍历哈夫曼树,按照编码字符串的位数依次访问左右分支。如果遇到叶节点,就将对应的字符记录下来,并重新回到根节点继续遍历;

2. 重复步骤1,直到编码字符串中的所有位数都被遍历完毕。

哈夫曼编码简单例题图

哈夫曼编码简单例题图

哈夫曼编码简单例题图

一、什么是哈夫曼编码

1.1 简介

哈夫曼编码是一种用于数据压缩的编码方式,由大卫·哈夫曼于1952年发明。它利用了数据的统计特性,根据出现频率对不同的字符进行编码,将出现频率高的字符用较短的编码表示,出现频率低的字符用较长的编码表示。

1.2 编码原理

哈夫曼编码的原理是通过构建哈夫曼树来生成编码表,根据字符出现的频率构建一棵二叉树,出现频率越高的字符离根节点越近,而出现频率越低的字符离根节点越远。通过遍历哈夫曼树,可生成每个字符对应的编码。

二、哈夫曼编码举例

2.1 示例

假设有一个包含5个字符的文本文件,字符及其出现频率如下:

字符频率

A 4

B 3

C 2

D 1

E 1

2.2 构建哈夫曼树

1.首先,将字符节点按照出现频率从小到大排序,得到序列:[D, E, C, B,

A]。

2.从序列中选取频率最小的两个字符节点(D和E),作为左右子节点构建一

个新的节点,该新节点的频率为D和E节点频率之和(1+1=2)。

3.将该新节点插入到序列中,得到新的序列:[C, B, A, DE]。

4.重复第2和第3步,直到序列中只剩下一个节点,即哈夫曼树的根节点。

2.3 生成编码表

1.从根节点出发,沿着左子树路径标记0,沿着右子树路径标记1。

2.当到达叶子节点时,记录路径上的编码。

字符频率编码

A 4 0

B 3 10

C 2 110

D 1 1110

E 1 1111

三、哈夫曼编码的应用

3.1 数据压缩

哈夫曼编码的主要应用是数据压缩。通过使用哈夫曼编码,出现频率高的字符用较短的编码表示,可以大大减小数据的存储空间。

数据结构哈夫曼编码实验报告-无删减范文

数据结构哈夫曼编码实验报告-无删减范文

数据结构哈夫曼编码实验报告

数据结构哈夫曼编码实验报告

实验背景

哈夫曼编码是一种常用的数据压缩方法,通过使用变长编码来表示不同符号,将出现频率较高的符号用较短的编码表示,从而达到压缩数据的目的。通过实现哈夫曼编码算法,我们能够更好地理解和掌握数据结构中的树形结构。

实验目的

1. 理解哈夫曼编码的原理及实现过程。

2. 掌握数据结构中树的基本操作。

3. 进一步熟悉编程语言的使用。

实验过程

1. 构建哈夫曼树

首先,我们需要根据给定的字符频率表构建哈夫曼树。哈夫曼树是一种特殊的二叉树,其叶子节点表示字符,而非叶子节点表示字符的编码。

构建哈夫曼树的过程如下:

1. 根据给定的字符频率表,将每个字符视为一个节点,并按照频率从小到大的顺序排列。

2. 将频率最小的两个节点合并为一个新节点,并将其频率设置为两个节点的频率之和。这个新节点成为新的子树的根节点。

3. 将新节点插入到原来的节点列表中,并继续按照频率从小到大的顺序排序。

4. 重复步骤2和步骤3,直到只剩下一个节点,这个节点即为哈夫曼树的根节点。

2. 哈夫曼编码表

在构建完哈夫曼树后,我们需要根据哈夫曼树每个字符的哈夫曼编码表。哈夫曼编码表是一个字典,用于存储每个字符对应的编码。

哈夫曼编码表的过程如下:

1. 从哈夫曼树的根节点出发,遍历整个树。

2. 在遍历的过程中,维护一个路径,用于记录到达每个字符节点的路径,0表示左子树,1表示右子树。

3. 当到达一个字符节点时,将路径上的编码存储到哈夫曼编码表中对应的字符键下。

3. 压缩数据

有了哈夫曼编码表后,我们可以使用哈夫曼编码对数据进行压缩。将原本以字符表示的数据,转换为使用哈夫曼编码表示的二进

数据结构哈夫曼编码实验报告

数据结构哈夫曼编码实验报告

数据结构哈夫曼编码实验报告

【正文】

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.构建哈夫曼树

接下来,我们使用统计得到的频率表构建哈夫曼树。哈夫曼树是一种

二叉树,每个内部节点都有两个子节点,分别代表0和1

首先,将频率表中的每个字符作为叶子节点,并按照频率从小到大进

行排序。

然后,依次选择频率最小的两个节点,将它们作为子节点创建一个新

的节点,并将新节点的频率设置为这两个节点频率之和。将新节点插入到

频率表中,然后删除原来的两个节点。

重复上述步骤,直到频率表中只剩下一个节点,即哈夫曼树的根节点。

3.生成编码表

根据构建好的哈夫曼树,我们可以生成字符的编码表。遍历哈夫曼树,记录从根节点到每个叶子节点的路径,其中0代表左子节点,1代表右子

节点。

4.压缩数据

通过编码表,我们可以将原始数据进行压缩。遍历原始文本,将每个字符替换为对应的编码,然后将所有编码拼接成一个二进制字符串。

5.存储压缩后的数据

将压缩后的二进制字符串进行存储,可以使用二进制文件或者文本文件存储。

6.解压数据

对于解压,我们需要加载压缩后的数据,并重新构建哈夫曼树。遍历压缩后的二进制字符串,根据哈夫曼树的结构逐个读取二进制位,当遇到叶子节点时,输出对应的字符。

通过上述步骤,我们可以实现对文本数据的压缩和解压。

需要注意的是,由于哈夫曼编码是基于字符频率进行优化的,所以对于不同的文本文件,编码效果也会有所不同。较为重复的字符出现频率高的文本文件,哈夫曼编码效果会更好。

数据结构哈夫曼树编码

数据结构哈夫曼树编码

数据结构哈夫曼树编码

一、引言

二、哈夫曼树的定义

1. 节点的概念

2. 哈夫曼树的定义

三、哈夫曼编码的概念

1. 编码方式

2. 码长和平均码长

四、哈夫曼编码的实现方法

1. 构建哈夫曼树

a. 构建思路及步骤

b. 构建示例图解

2. 编码过程

a. 编码步骤及示例图解

b. 编码实现代码示例

3. 解码过程

a. 解码步骤及示例图解

b. 解码实现代码示例

五、哈夫曼编码的优缺点

1. 优点

2. 缺点

六、应用实例

七、总结

一、引言:

随着信息技术的飞速发展,数据处理已经成为当今社会中一个不可或缺的部分。在数据处理中,如何高效地压缩数据是一个非常重要的问题。而哈夫曼树编码作为一种高效的压缩算法,在数据传输和存储方面有着广泛应用。

二、哈夫曼树的定义:

1. 节点的概念:

哈夫曼树是一种二叉树,由根节点、左子树和右子树组成。每个节点可以有零个或两个子节点。叶子节点是指没有子节点的节点,而非叶子节点则至少有一个子节点。

2. 哈夫曼树的定义:

哈夫曼树是一种特殊的二叉树,它的所有叶子节点都带有权值。对于任意一个哈夫曼树,将其所有叶子节点按照权值从小到大排列,则可得到一组序列W={w1,w2,...,wn}。哈夫曼树的构建过程就是将这组序列转化为一棵二叉树。

三、哈夫曼编码的概念:

1. 编码方式:

哈夫曼编码是一种前缀编码方式,即每个字符的编码都不是其他字符编码的前缀。

2. 码长和平均码长:

对于一个字符c,其在哈夫曼编码中所占用的位数称为其码长Lc。而整个字符串的平均码长Lavg则是所有字符在哈夫曼编码中所占用位数之和除以字符串长度n。

哈夫曼树构造例题

哈夫曼树构造例题

哈夫曼树构造例题

摘要:

1.哈夫曼树的基本概念

2.哈夫曼树的构造方法

3.哈夫曼编码的生成

4.哈夫曼编码的应用

正文:

哈夫曼树构造例题

哈夫曼树是一种用于数据压缩的树形结构,它能将原始数据转换成对应的哈夫曼编码,从而实现压缩。哈夫曼树构造例题将详细介绍哈夫曼树的基本概念、构造方法、哈夫曼编码的生成以及哈夫曼编码的应用。

1.哈夫曼树的基本概念

哈夫曼树是一种满二叉树,它的每个节点都包含一个字符,叶子节点对应原始数据的字符。哈夫曼树的构造过程是通过反复合并出现频率最小的节点来完成的。

2.哈夫曼树的构造方法

哈夫曼树的构造方法分为以下几个步骤:

(1) 将原始数据的字符按照出现频率构建一个哈夫曼树。

(2) 从哈夫曼树中选出出现频率最小的两个节点进行合并,得到一个新的节点,新节点的出现频率为两个节点出现频率之和。

(3) 将新节点插入到哈夫曼树中,更新哈夫曼树的结构。

(4) 重复步骤(2) 和(3),直到哈夫曼树中只剩下一个节点,这个节点就是哈夫曼树的根节点。

3.哈夫曼编码的生成

哈夫曼编码是根据哈夫曼树生成的,它的每个字符都对应一个唯一的编码。从根节点到达每个叶子节点的路径代表该字符的编码,其中左子节点的边表示“0”,右子节点的边表示“1”。

4.哈夫曼编码的应用

哈夫曼编码在数据压缩领域有着广泛的应用,它能有效地将原始数据转换成较短的二进制编码,从而减少存储空间和传输时间。除了数据压缩,哈夫曼编码还可以用于其他领域,如信息论、计算机科学等。

总之,哈夫曼树构造例题详细介绍了哈夫曼树的基本概念、构造方法、哈夫曼编码的生成以及哈夫曼编码的应用。

数据结构实验报告(哈夫曼树)

数据结构实验报告(哈夫曼树)

数据结构实验报告实验题目:Huffman编码与解码

姓名:

学号:

院系:

实验名称:

Huffman编码与解码实验

问题描述:

本实验需要以菜单形式完成以下功能:

1.输入电文串

2.统计电文串中各个字符及其出现的次数

3.构造哈弗曼树

4.进行哈弗曼编码

5.将电文翻译成比特流并打印出来

6.将比特流还原成电文

数据结构的描述:

逻辑结构:

本实验可用二叉树实现,其逻辑结构为一对二的形式,即一个结点对应两个结点。在实验过程中我们也应用到了栈的概念。

存储结构:

使用结构体来对数据进行存储:

typedef struct

{

int weight;

int parent,lc,rc;

}HTNode,*HuffmanTree;

typedef struct LNode

{

char *elem;

int stacksize;

int top;

}SqStack;

在main函数里面定义一个哈弗曼树并实现上述各种功能。

程序结构的描述:

本次实验一共构造了10个函数:

1.void HuffTree(HuffmanTree &HT,int n[],int mun);

此函数根据给定的mun个权值构建哈弗曼树,n[]用于存放num个权值。

2.void Select(HuffmanTree &HT,int n,int i,int &s1,int &s2);

此函数用于在HT[1,i-1]中选择parent为0且weight为最小的两个结点,其下标分别为s1,s2.

3.void HuffmanCoding(HuffmanTree HT,char **&HC,int n);

(完整word版)哈工大数据结构大作业——哈夫曼树生成、编码、遍历

(完整word版)哈工大数据结构大作业——哈夫曼树生成、编码、遍历

一、问题描述

1.用户输入字母及其对应的权值,生成哈夫曼树;

2.通过最优编码的算法实现,生成字母对应的最优0、1编码;

3.先序、中序、后序遍历哈夫曼树,并打印其权值。

二、方法思路

1。哈夫曼树算法的实现

§存储结构定义

#define n 100 /*叶子树*/

#define m 2*(n) –1 /* 结点总数*/

typedef struct {/*结点型*/

double weight ; /* 权值*/

int lchild ;/* 左孩子链*/

int rchild ;/* 右孩子链*/

int parent; /*双亲链*/ 优点?

}HTNODE ;

typedef HTNODE HuffmanT[ m ];

/*huffman树的静态三叉链表表示*/

算法要点

1)初始化:将T[0],…T[m—1]共2n-1个结点的三个链域均置空(—1 ),权值为0;

2)输入权值:读入n 个叶子的权值存于T的前n 个单元

T[0],…T[n],它们是n 个独立的根结点上的权值;

3)合并:对森林中的二元树进行n—1次合并,所产生的新结点

依次存放在T[i](n〈=i<=m—1)。每次合并分两步:

(1) 在当前森林中的二元树T [0],…T[i—1]所有结点中选取权值

最小和次最小的两个根结点T[p1]和T[p2]作为合并对象,这

里0<= p1,p2<= i –1;

(2) 将根为T[p1]和T[p2]的两株二元树作为左、右子树合并为一

株新二元树,新二元树的根结点为T[i]。即

T[p1].parent =T[p2].parent = i ,T[i].lchild= p1, T[i]。

数据结构叉树及哈夫曼编码

数据结构叉树及哈夫曼编码

甘肃政法学院

本科学生实验报告

(三)

姓名:

学院:

专业:

班级:

实验课程名称:数据结构

指导教师及职称:

开课时间:

三、实验内容与步骤:

1..二叉树的创建及输出。Btree.cpp文件

工程文件.cpp。

Btree.h文件

运行结果如下

2.根据哈夫曼树哈夫输出曼编码:j.cpp文件

工程文件.cpp

a.h文件。

运行结果如下:

3.线段树的输出。z.cpp文件。

工程文件.cpp

S.h文件。

运行结果如下:

5.树的输出。

6.二叉树的先序和中序及高度。

运行结果如下:

四、实验总结:

1.树是由n(n≥0)个结点组成的有限集合。树的遍历运算是指按某种方式访问树中的每一个结点且每一个结点只被访问一次

先根遍历,即先访问根结点,然后按照从左到右的次序先根遍历根结点的每一棵子树。后根遍历,即先按照从左到右的次序后根遍历根结点的每一棵子树然后访问根结点。一个结点所在的层次为其双亲结点所在的层次加1。树中结点的最大层次称为树的高度(或树的深度)。

2.用先序建树的时候虽然只要输入一个字符串,但是要判断空树的情况。比较麻烦,我个人觉得用先序与中序联合建树比较简单。因为这样只要输入先序与中序就可以建树了。

3. 对于二叉树的三种遍历的过程,要是用递归写的就根据书上所给出的遍历步骤做稍微的调整就好了。至于非递归的三种遍历,中序最为简单,用一个栈就可以完成了,思路是边进栈边收索左孩子,直到左孩子为空的时候才开始进行出栈输出再收索右孩子的操作。而非递归的先序遍历基本可以和中序一样,建立一个队列,在进栈的时候队列也进同样的元素,但是不与栈一起出栈。而是在最后进栈出栈结束的时候,对队列进行出队列操作即可。在创建二叉树时CreateBTNode(*b,*str) 用ch扫描采用括号表示法表示二叉树的字符串。分以下几种情况:

哈夫曼树的建立及操作

哈夫曼树的建立及操作

实验六哈夫曼树的建立与操作

一、实验要求和实验内容

1、输入哈夫曼树叶子结点〔信息和权值〕

2、由叶子结点生成哈夫曼树内部结点

3、生成叶子结点的哈夫曼编码

4、显示哈夫曼树结点顺序表

二、实验要点:

根据哈夫曼算法,建立哈夫曼树时,可以将哈夫曼树定义为一个构造型的一维数组HuffTree,保存哈夫曼树中各结点的信息,每个结点包括:权值、左孩子、右孩子、双亲,如图5-4所示。由于哈夫曼树中共有2n-1个结点,并且进展n-1次合并操作,所以该数组的长度为2n-1。

构造哈夫曼树的伪代码如下:

在哈夫曼树中,设左分支为0,右分支为1,从根结点出发,遍历整棵哈夫曼树,求得各个叶子结点所表示字符的哈夫曼编码。

三、.函数的功能说明及算法思路

BTreeNode* CreateHuffman(ElemType a[],int n)//构造哈夫曼树

1.对给定n个权值{a1,a2,…,an}的叶子结点,构成具有n棵二叉树的森林F={T1,T2,…,Tn}, 其中每棵二叉树Ti只有一个权值为ai的根结点,其左右子树为空。

2.在F中选取两棵根结点的权值最小的树作为左右子树构造一棵新的二叉树,且新的二叉树的根结点的权值为其左右子树上根结点的权值之和。

3.从F中删除构成新树的两棵树,并把新树参加到F中。

4.重复 2、3两步,直到F只有一棵树为止。则F中的树就是哈夫曼树。

void PrintBTree(BTreeNode *BT)//以广义表形式输出哈夫曼树

主要用到了递归的思想。

void HuffManCoding(BTreeNode *BT, int len)//求哈夫曼编码

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

一、问题描述

1.用户输入字母及其对应的权值,生成哈夫曼树;

2.通过最优编码的算法实现,生成字母对应的最优0、1编码;

3.先序、中序、后序遍历哈夫曼树,并打印其权值。

二、方法思路

1.哈夫曼树算法的实现

§存储结构定义

#define n 100 /* 叶子树*/

#define m 2*(n) –1 /* 结点总数*/

typedef struct { /* 结点型*/

double weight ; /* 权值*/

int lchild ; /* 左孩子链*/

int rchild ; /* 右孩子链*/

int parent; /* 双亲链*/ 优点?

}HTNODE ;

typedef HTNODE HuffmanT[ m ] ;

/* huffman树的静态三叉链表表示*/

算法要点

1)初始化:将T[0],…T[m-1]共2n-1个结点的三个链域

均置空( -1 ),权值为0;

2)输入权值:读入n 个叶子的权值存于T的前n 个单元

T[0],…T[n], 它们是n 个独立的根结点上的权值;

3)合并:对森林中的二元树进行n-1次合并,所产生的新

结点

依次存放在T[i](n<=i<=m-1)。每次合并分两步:

(1) 在当前森林中的二元树T [0],…T[i-1]所有结点中

选取权值

最小和次最小的两个根结点T[p1]和T[p2]作为合并对象,这

里0<= p1,p2<= i –1;

(2) 将根为T[p1]和T[p2]的两株二元树作为左、右子树

合并为一

株新二元树,新二元树的根结点为T[i]。即

T[p1].parent =T[p2].parent = i ,T[i].lchild= p1,

T[i].rchild=p2,T[i].weight =T[p1].weight +

T[p2].weight。

2.用huffman算法求字符集最优编码的算法:

1) 使字符集中的每个字符对应一株只有叶结点的二叉树,叶的权值为对应字符的使用频率;

2) 利用huffman算法来构造一株huffman树;

3) 对huffman树上的每个结点,左支附以0,右支附以1(或者相反),则从根到叶的路上的0、1序列就是相应字符的编码Huffman编码实现:

存储结构

typedef struct{

char ch; //存储字符

char bits[n+1]; //字符编码位串

}CodeNode;

typedef CodeNode HuffmanCode[n];

HuffmanCode H;

3.二叉树遍历的递归定义

先根顺序遍历二叉树:

若二叉树非空则:

{

访问根结点;

先根顺序遍历左子树;

先根顺序遍历右子树;

}

中根顺序遍历二叉树:

若二叉树非空则:

{

中根顺序遍历左子树;

访问根结点;

中根顺序遍历右子树;

}

后根顺序遍历二叉树:

若二叉树非空则:

{ 后根顺序遍历左子树;

后根顺序遍历右子树;

访问根结点;

} ;

三、主要数据结构及源程序代码及其注释

1.扩充二叉树:内结点、外结点

(增长树)

2.哈夫曼树

3.Huffman编码实现

源程序代码及注释

#include"stdafx.h"

#include

#include

#include

#define n 10

#define m 2*(n)-1

typedef struct//建立哈夫曼结点结构体

{

char data;

float weight;

int lchild;

int rchild;

int parent;

}htnode;

typedef struct//建立哈夫曼编码结构体

{

char ch;

char bits[n+1];

}htcode;

void SelectMin(htnode T[m],int nn,int&p1,int&p2)//选择哈夫曼树所有结点中权值最小的两个根结点

{

int i,j;

for(i=0;i<=nn;i++)

{

if(T[i].parent==-1)

{

p1=i;

break;

}

}

for(j=i+1;j<=nn;j++)

{

if(T[j].parent==-1)

{

p2=j;

break;

}

}

for(i=0;i<=nn;i++)

{

if((T[p1].weight>T[i].weight)&&(T[i].parent==-1)

&&(p2!=i))

p1=i;

}

for(j=0;j<=nn;j++)

{

if((T[p2].weight>T[j].weight)&&(T[j].parent==-1)

&&(p1!=j))

p2=j;

}

}

void CreatHT(htnode T[m])//建立哈夫曼树

{

int i,p1,p2;

for(i=0;i

{

T[i].parent=T[i].lchild=T[i].rchild=-1;//赋初值

}

for(i=n;i

{

SelectMin(T,i-1,p1,p2);

T[p1].parent=T[p2].parent=i;

if(T[p1].weight

T[i].lchild=p1;

T[i].rchild=p2;

}

else{

T[i].lchild=p2;

T[i].rchild=p1;

}

T[i].weight=T[p1].weight+T[p2].weight;

}

}

void HuffmanEncoding(htnode T[m],htcode C[n])//哈夫曼编码{

int c,p,i;

char cd[n+1];

int start;

相关文档
最新文档