数据结构课程设计-哈夫曼编码实验报告
南邮数据结构实验一

实验报告(2014 / 2015 学年第一学期)课程名称数据结构实验名称二叉树基本操作以及哈夫曼编码译码系统实验时间年月日指导单位指导教师学生姓名班级学号学院(系) 专业二叉树的基本运算:一、问题描述1.设计递归算法,实现二叉树的运算:删除一棵二叉树,求一棵二叉树的高度,求一棵二叉树中叶子节点数,复制一棵二叉树,交换一棵二叉树的左右子树2.设计算法,自上而下,自左向右即按层次遍历一棵二叉树3.设计main函数,测试上述每个运算二、系统分析和概要设计首先用maketree构造一棵二叉树,然后遍历二叉树,然后交换每个结点的左右子树,接着算出输得高度和叶子节点,最后删除。
三、详细设计2. 核心算法建立二叉树的void MakeTree(const T& x,BinaryTree<T>& left,BinaryTree<T>& right)和计算叶子节点的int Size();3. 算法分析删除一棵二叉树,求一棵二叉树的高度,求一棵二叉树中叶子节点数,复制一棵二叉树等都是用递归的方法实现。
四、程序代码流程图#include<iostream.h>template<class T>struct BTNode{BTNode(){lChild=rChild=NULL;}BTNode(const T &x){element=x;lChild=rChild=NULL;}BTNode(const T &x,BTNode<T>* l,BTNode<T>* r){element=x;lChild=l;rChild=r;}T element;BTNode<T>* lChild,* rChild;};template<class T>class BinaryTree{public:BinaryTree(){root=NULL;}~BinaryTree(){Clear();}void Copy(BinaryTree<T> &r) const;bool IsEmpty()const{return root == NULL;}void Clear();void Exchange();bool Root(T& x)const;int GetHeight();void MakeTree(const T& x,BinaryTree<T>& left,BinaryTree<T>& right);void BreakTree(T& x,BinaryTree<T>& left,BinaryTree<T>& right);void PreOrder(void (*Visit)(T &x));void LevelOrder(void (*Visit)(T& x));int Size();BinaryTree<T>(BinaryTree<T> &t)root=Copy(t.root);}// void InOrder(void (*Visit)(T &x));// void PostOrder(void (*Visit)(T &x));BTNode<T>* Copy(BTNode<T>* t);protected:BTNode<T> * root;private:static int number;void Clear(BTNode<T>* &t);void Exchange(BTNode<T>* t);int GetHeight(BTNode<T>* t);int Size(BTNode<T>* t);void PreOrder(void (*Visit)(T &x),BTNode<T>* t);void LevelOrder(void (*Visit)(T& x),BTNode<T>* t); // void InOrder(void (*Visit)(T &x),BTNode<T>* t);// void PostOrder(void (*Visit)(T &x),BTNode<T>* t); };template <class T>bool BinaryTree<T>::Root(T &x)const{if(root){x=root->element;return true;}elsereturn false;}template <class T>void BinaryTree<T>::Clear(){Clear(root);}template <class T>void BinaryTree<T>::Clear(BTNode<T>* &t){if(t)Clear(t->lChild);Clear(t->rChild);delete t;t=NULL;}}template <class T>void BinaryTree<T>::MakeTree(const T& x,BinaryTree<T>& left,BinaryTree<T>& right) {if(root||&left==&right)return;root=new BTNode <T>(x,left.root,right.root);left.root=right.root=NULL;}template <class T>void BinaryTree<T>::BreakTree(T& x,BinaryTree<T>& left,BinaryTree<T>& right) {if(!root||&left==&right||left.root||right.root)return;x=root->element;left.root=root->lChild;right.root=root->rChild;delete root;root=NULL;}template <class T>BTNode<T>* BinaryTree<T>::Copy(BTNode<T>* t){if(!t)return NULL;BTNode<T>*q=new BTNode<T>(t->element);q->lChild=Copy(t->lChild);q->rChild=Copy(t->rChild);return q;}template <class T>void Visit(T &x){cout<<x<<" ";}template <class T>void BinaryTree<T>::PreOrder(void (*Visit)(T& x)){PreOrder(Visit,root);}template <class T>void BinaryTree<T>::PreOrder(void (*Visit)(T& x),BTNode<T>* t) {if(t){Visit(t->element);PreOrder(Visit,t->lChild);PreOrder(Visit,t->rChild);}}template <class T>void BinaryTree<T>::Exchange(){Exchange(root);}template <class T>void BinaryTree<T>::Exchange(BTNode<T>* t){if(!t)return;BTNode<T>* temp;temp=t->lChild;t->lChild=t->rChild;t->rChild=temp;Exchange(t->lChild);Exchange(t->rChild);}template <class T>int BinaryTree<T>::GetHeight(){return GetHeight(root);}int BinaryTree<T>::GetHeight(BTNode<T>* t){int templ;int tempr;if(!t)return 0;templ=GetHeight(t->lChild);tempr=GetHeight(t->rChild);if(templ++>tempr++)return templ;elsereturn tempr;}template <class T>int BinaryTree<T>::number=0;template <class T>int BinaryTree<T>::Size(){Size(root);return number;}template <class T>int BinaryTree<T>::Size(BTNode<T>* t){if(t!=NULL){Size(t->lChild);if(t->lChild ==NULL&&t->rChild ==NULL)number++;Size(t->rChild);}return number;}template <class T>void BinaryTree<T>::LevelOrder(void (*Visit)(T& x)) {PreOrder(Visit,root);}void BinaryTree<T>::LevelOrder(void (*Visit)(T& x),BTNode<T>* t) {BTNode *quene[50],*p;int pre=1,rear=1;quene[++pre]=t;while(pre!=0){p=quene[++rear];cout<<p->element<<" ";if(p->lChild !=NULL)quene[++pre]=p->rChild ;if(p->rChild !=NULL)quene[++pre]=p->lChild ;}}void main(){BinaryTree <char> a,b,x,y,z;y.MakeTree('E',a,b);z.MakeTree('F',a,b);x.MakeTree('C',y,z);y.MakeTree('D',a,b);z.MakeTree('B',y,x);cout<<"二叉树z的先序遍历:"<<endl;z.PreOrder(Visit);cout<<endl;cout<<"层次遍历二叉树:";z.LevelOrder(Visit);cout<<endl;BinaryTree<char> q(z);cout<<"复制的二叉树q的先序遍历:"<<endl;q.PreOrder(Visit);cout<<endl;cout<<"树的高度:";cout<<z.GetHeight()<<endl;cout<<"叶子节点数量:";cout<<z.Size()<<endl;z.Exchange();cout<<"二叉树左右子树交换后的先序遍历:"<<endl;z.PreOrder(Visit);cout<<endl;}五、测试用例和运行结果测试用例如main函数中所示,结果如下图所示。
编码仿真实验报告(3篇)

第1篇实验名称:基于仿真平台的编码算法性能评估实验日期:2023年4月10日实验地点:计算机实验室实验目的:1. 了解编码算法的基本原理和应用场景。
2. 通过仿真实验,评估不同编码算法的性能。
3. 分析编码算法在实际应用中的优缺点。
实验环境:1. 操作系统:Windows 102. 编译器:Visual Studio 20193. 仿真平台:MATLAB 2020a4. 编码算法:Huffman编码、算术编码、游程编码实验内容:1. 编写Huffman编码算法,实现字符序列的编码和解码。
2. 编写算术编码算法,实现字符序列的编码和解码。
3. 编写游程编码算法,实现字符序列的编码和解码。
4. 在仿真平台上,分别对三种编码算法进行性能评估。
实验步骤:1. 设计Huffman编码算法,包括构建哈夫曼树、编码和解码过程。
2. 设计算术编码算法,包括编码和解码过程。
3. 设计游程编码算法,包括编码和解码过程。
4. 编写仿真实验代码,对三种编码算法进行性能评估。
5. 分析实验结果,总结不同编码算法的优缺点。
实验结果及分析:一、Huffman编码算法1. 编码过程:- 对字符序列进行统计,计算每个字符出现的频率。
- 根据频率构建哈夫曼树,叶子节点代表字符,分支代表编码。
- 根据哈夫曼树生成编码,频率越高的字符编码越短。
2. 解码过程:- 根据编码,从哈夫曼树的根节点开始,沿着编码序列遍历树。
- 当遍历到叶子节点时,输出对应的字符。
3. 性能评估:- 编码长度:Huffman编码的平均编码长度最短,编码效率较高。
- 编码时间:Huffman编码算法的编码时间较长,尤其是在构建哈夫曼树的过程中。
二、算术编码算法1. 编码过程:- 对字符序列进行统计,计算每个字符出现的频率。
- 根据频率,将字符序列映射到0到1之间的实数。
- 根据映射结果,将实数序列编码为二进制序列。
2. 解码过程:- 对编码的二进制序列进行解码,得到实数序列。
树及其应用实验报告(3篇)

第1篇一、实验目的本次实验旨在让学生掌握树的基本概念、数据结构及其应用,包括二叉树、树型结构、哈夫曼树等。
通过实验,加深对数据结构理论知识的理解,提高编程能力和实际应用能力。
二、实验环境1. 操作系统:Windows 102. 编程语言:Python3. 开发工具:PyCharm三、实验内容1. 实现二叉树2. 中序先序序列构造二叉树3. 决策树4. 表达式树5. 实现二叉查找树6. 红黑树源码分析7. 哈夫曼树及其应用四、实验步骤及结果1. 实现二叉树实现二叉树的基本操作,包括创建节点、插入节点、删除节点、查找节点、遍历等。
```pythonclass TreeNode:def __init__(self, value):self.value = valueself.left = Noneself.right = Nonedef insert_node(root, value):if root is None:return TreeNode(value)if value < root.value:root.left = insert_node(root.left, value) else:root.right = insert_node(root.right, value) return rootdef inorder_traversal(root):if root:inorder_traversal(root.left)print(root.value, end=' ')inorder_traversal(root.right)创建二叉树并插入节点root = Nonevalues = [8, 3, 10, 1, 6, 14, 4, 7, 13]for value in values:root = insert_node(root, value)中序遍历二叉树print("中序遍历结果:")inorder_traversal(root)```2. 中序先序序列构造二叉树根据给定的中序和先序序列构造二叉树。
哈夫曼编码1952年Huffma...

第三章多媒体数据压缩3.1 数据压缩的基本原理和方法3.1 数据压缩的基本原理和方法•压缩的必要性音频、视频的数据量很大,如果不进行处理,计算机系统几乎无法对它进行存取和交换。
例如,一幅具有中等分辨率(640×480)的真彩色图像(24b/像素),它的数据量约为7.37Mb/帧,一个100MB(Byte)的硬盘只能存放约100帧图像。
若要达到每秒25帧的全动态显示要求,每秒所需的数据量为184Mb,而且要求系统的数据传输率必须达到184Mb/s。
对于声音也是如此,若采用16b样值的PCM编码,采样速率选为44.1kHZ ,则双声道立体声声音每秒将有176KB的数据量。
3.1 数据压缩的基本原理和方法•视频、图像、声音有很大的压缩潜力信息论认为:若信源编码的熵大于信源的实际熵,该信源中一定存在冗余度。
原始信源的数据存在着很多冗余度:空间冗余、时间冗余、视觉冗余、听觉冗余等。
3.1.1 数据冗余的类型•空间冗余:在同一幅图像中,规则物体和规则背景的表面物理特性具有相关性,这些相关性的光成像结果在数字化图像中就表现为数据冗余。
–一幅图象中同一种颜色不止一个象素点,若相邻的象素点的值相同,象素点间(水平、垂直)有冗余。
–当图象的一部分包含占主要地位的垂直的源对象时,相邻线间存在冗余。
3.1.1 数据冗余的类型•时间冗余:时间冗余反映在图像序列中就是相邻帧图像之间有较大的相关性,一帧图像中的某物体或场景可以由其它帧图像中的物体或场景重构出来。
–音频的前后样值之间也同样有时间冗余。
–若图象稳定或只有轻微的改变,运动序列帧间存在冗余。
3.1.1 数据冗余的类型•信息熵冗余:信源编码时,当分配给第i 个码元类的比特数b (y i )=-log p i ,才能使编码后单位数据量等于其信源熵,即达到其压缩极限。
但实际中各码元类的先验概率很难预知,比特分配不能达到最佳。
实际单位数据量d>H (S ),即存在信息冗余熵。
数据结构与算法——电文的编码和译码

电文的编码和译码1.问题描述从键盘接受一串电文字符,输出对应的哈夫曼编码;同时能翻译由哈夫曼编码生成的代码串,输出对应的电文字符串。
2.设计要求(1)构造一棵哈夫曼树。
(2)实现哈夫曼编码,并用哈夫曼编码生成的代码进行译码。
(3)程序中字符和权值是可变的,实现程序的灵活性。
3.数据结构本课程设计采用结构体数组作为数据结构,来储存哈夫曼树及其编码。
4.分析与实现在电报通信中,电文是以二进制代码传送的。
在发送时,需要将电文中的字符转换成二进制代码串,即编码;在接收时,要将收到的二进制代码串转化成对应的字符序列,即译码。
字符被使用的频率是非均匀的。
在传送电文时,要想使电文总长尽可能短,就需要让使用频率高的字符编码长度尽可能短。
因此,若对某字符集进行不定长编码设计,则要求任一一个字符编码都不能使其他字符编码的前缀,这种编码称作前缀编码。
由哈弗曼树求得的编码是最优前缀码,也称哈夫曼编码。
给出字符集和各个字符的概率分布,构造哈弗曼树,将哈夫曼树中每个分支结点的左分支标0,右分支标1,从根到每个叶子的路径上的标号连起来就是给叶子所代表字符的编码。
(1)构造哈夫曼树根据哈弗曼算法,若已知n个叶结点,则构造的哈弗曼树有2n-1个结点。
第一步:先输入字符集中的n个字符(叶结点)和表示其概率分布的权值,储存在ht (HuffNode型)数组的前n个数组元素中。
然后将2n-1个结点的双亲和孩子结点均置为0。
第二步:在所有的结点中,选取双亲为零且具有最小权值m1和次小权值m2的两个结点,用p1和p2指示这两个结点在数组中的位置。
将根为ht[p1]和ht[p2]的两棵树合并,使其成为新结点ht[i]的左右孩子,ht[i]的权值为最小权值m1和次小权值m2之和;ht[p1]和ht[p2]的双亲指向i。
共进行n-1次合并,产生n-1个结点,依次放入ht数组中数组下标从n+1到2n-1。
这样就构成了一棵哈夫曼树。
(2)编码基本思想是:从哈弗曼树的叶结点ht[i] (1≤i≤n)出发,通过双亲parent找到其双亲ht[f],通过ht[f]的域left和right,可知ht[i]是ht[f]的左分支还是右分支,若是左分支,生成的代码0;若是右分支,生成代码1。
数据结构-哈夫曼树及其应用

15
40 a
30 b
5
c
10 d
15 e
二、哈夫曼树及其应用
2.哈夫曼树的求解过程 ③实例:已知有5个叶子结点的权值分别为:5 , 15 , 40 , 30 , 10 ;试画出一棵相应的哈夫曼树。
30
40 a
30 b
15
15 e
5
c
10 d
二、哈夫曼树及其应用
2.哈夫曼树的求解过程 ③实例:已知有5个叶子结点的权值分别为:5 , 15 , 40 , 30 , 10 ;试画出一棵相应的哈夫曼树。
WPL=∑wi*li最小的二叉树称为“最优
i=1 n
二叉树”或称为“哈夫曼树”。
二、哈夫曼树及其应用
2.哈夫曼树的值为{w1,w2,...wn},构 造一棵最优二叉树。
二、哈夫曼树及其应用
2.哈夫曼树的求解过程 ②方法:
步骤1:构造一个具有n棵二叉树的森林F={T1,T2,......,Tn}, 其中Ti是只有一个根结点且根结点的权值为wi的二叉树。 步骤2:在F中选取两棵其根结点的权值最小的二叉树,从F 中删除这两棵树,并以这两棵二叉树为左右子树构造一棵 新的二叉树添加到F中,该新的二叉树的根结点的权值为 其左右孩子二叉树的根结点的权值之和。 步骤3:判断F中是否只有唯一的一棵二叉树。若是,则求 解过程结束;否则,转步骤2。
二、哈夫曼树及其应用
3.哈夫曼编码 ②压缩编码:
例如:对于刚才的4个字符的编码问题,可以按如 下不等长编码方案进行编码: A: 0 B: 00 C: 1 D: 01 则对于电文“ABACCDA”的二进制电码为: 000011010 总长为9位 问题:译码时可能出现多意性,即译码不唯一:
二、哈夫曼树及其应用
数据结构课程设计

《数据结构》课程设计实践指导书一、实践的目的和任务《数据结构》课程设计是计算机科学技术专业集中实践性环节之一,是学习完《数据结构》课程后进行的一次全面的综合练习。
开设本课程设计实践的主要目的就是要达到理论与实际应用相结合,提高学生的动手能力,完成计算机应用能力的培养;主要任务是通过对给定问题的求解,使学生在运用《数据结构》、程序设计以及其它所学课程中的各种基本技术和理论,在建立问题模型、构造求解算法、设计数据结构、编程及上机调试等方面得到全面的锻炼,从而能更深刻地理解《数据结构》的精髓,为后续软件课程的学习及软件设计能力的提高奠定良好的基础。
二、实践的内容和要求(一)实践内容实践内容为数据结构课程完成后,运用《数据结构》、程序设计以及其它所学课程中的知识和技术来解决实际的问题。
在解决实际应用性问题时,按照计算机解决问题的步骤进行以下几个方面的工作:采用简明、严格的问题描述,建立模型,设计求解方法,用计算机实现求解方法,最后进行测试和文档制作。
1、建立模型许多问题的最初描述既不精确又不简练,还有一些问题不可能简单而精确地用计算机可求解的形式来描述,即使有些可用计算机求解的问题,也需要在很大范围内确定问题的参数,而那些合理的参数值只有通过实验才能确定。
因此,要用计算机解决问题,必须首先要以简明、严格的方式将问题描述清楚。
数学或其它科学中的几乎所有分支都可作为某一类具体问题的抽象模型。
例如,在涉及到若干对象及其相互间关系的问题时所用的数学模型为图论;数值计算问题中常用的数学模型为线性方程组(用于求解电路的电流强度或结构中的应力)或微分方程(用于预报人口增长情况或化学反应速度等);在符号与文本处理问题时常用字符串及形式语法作为模型(如编译系统)。
《数据结构》课程中所介绍的各种结构均可作为一种模型。
2、构造算法对问题建立了适当的数学模型后,就可以依据这一模型求解。
最初的目标是给出一个算法形式的解法,这是设计的核心部分。
6.6哈夫曼编码

如何编程实现Huffman编码?
建议1:Huffman树中结点的结构可设计成5分量形式:
char weight parent lchild rchild
建议2: Huffman树的存储结构可采用顺序存储结构: 将整个Huffman树的结点存储在一个数组HT[1..n..m]中; 各叶子结点的编码存储在另一“复合”数组HC[1..n]中。
频度高的信息 用短码,反之 用长码,传输 效率肯定高!
令d=0;i=10,a=110,n=111,则: WPL2=1bit×7+2bit×5+3bit×(2+4)=35 明确:要实现Huffman编码,就要先构造Huffman树
例:假设字符A,B,C,D,E的出现概率为42, 28, 15, 10, 5。求电文的总长度最短的一种编码?
中序遍历的非递归算法或称迭代算法或称迭代算法见教材见教材p131p131设高度为h的二叉树上只有度为0的结点和度为2的结点则此类二叉树所包含的结点数至少为至多为已知某二叉树的后序遍历序列是dabec中序遍历序列是debac则它的前序遍历序列是已知某二叉树的前序遍历序列是abdgcefh中序遍历序列是dgbaechf则其后序遍历序列是某二叉树的前序序列为stuwv中序序列为uwtvs则其后序序列为任何一棵二叉树的叶结点在先序中序和后序遍历序列中的相对次序实现任意二叉树的后序遍历的非递归算法而不使用栈结构最佳方案是二叉树采用存储结构线索二叉树是一种结构一棵二叉树的结点的数据结构采用顺序存储见数组t则其二叉链表表示形式为
想一想:对它中序遍历之后是什么效果?
什么是带权树?
即路径带有权值。例如:
7
5
2
4
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
数据结构课程设计报告
实验二哈夫曼编码
目录
一.问题描述及分析p1
1.问题描述p1
2.需求分析p1 二.功能模块及数据结构描述p1
1.数据结构描述 p1 2.模块描述 p2
三.主要算法流程描述p2
1.编码流程图 p3 2.译码流程图 p4
四.使用说明p5 五.调试分析说明p6
一.问题描述及分析
1.问题描述
设计一个哈夫曼编码/译码系统,对一个文本文件中的字符进行哈夫曼编码,生成编码文件(后缀名.cod);反过来,可将一个编码文件还原为一个文
本文件(.txt)。
2.需求分析
(1)输入一个待压缩的文本文件名,统计文本文件中各字符的个数作为权值,生成哈夫曼树;
(2)将文本文件利用哈夫曼树进行编码,生成编码文件(后缀名cod);
(3)输入一个待解压的压缩文件名称,并利用相应的哈夫曼树将编码序列译码;
(4)显示指定的编码文件和文本文件;
3.运行要求
.Windows xp/2003
.VC++6.0(或以上)运行库
二.功能模块及数据结构描述
1.数据结构描述
typedef struct
{
long weight;
long lchild,rchild,parent;
}hfmt;
hfmt t[2*256-1];
存放哈夫曼树结构体,weight为节点权值,lchild,rchild为节点的左右孩子在向量中的下标(为叶节点时,两值为:-1),parent为节点的双亲在向量中的
下标(用来区别根与非根节点,值为-1与非-1)。
typedef struct
{
char bits[256];
long s;
}hfmcc;
hfmcc cc[256];
存放哈夫曼编码结构体,s用来指示编码在位串bits[n]中的起始位置。
2.模块描述
图2.1 系统函数
copy函数:根据s的值在位串bits[n]中提取有效编码位数。
HFM函数:对读入的节点权值,生成哈夫曼树。
HFMBM函数:对生成的哈夫曼树进行零一编码,对应于原文件字符。
三.主要算法流程描述
1.编码流程图
图2.2 编码流程图
2.译码流程图
图2.3 译码流程图
四.使用说明
图2.4 生成的文件本软件默认生成的编码文件名为:a.cod
默认生成的译码文件名为:b.txt
执行提示:输入所要编码的文本文件。
图2.5 编码过程
编码完成,默认生成a.cod文件,等待译码。
输入所要译码的cod文件:
图2.6 译码过程
译码完成,默认生成b.txt文档文件。
五.调试分析说明
表2.1 调试遇到的问题及解决方案
六.参考文献
1、严蔚敏,吴伟民,《数据结构》(C语言版)[M],北京:清华大学出版社
2、严蔚敏,《数据结构习题集与上机指导》[M],北京:清华大学出版社
3、徐德民,《最新C语言程序设计》[M],电子工业出版社,1992
4、张国峰,《C++语言及其程序设计教程》[M],电子工业出版社,1992。