哈夫曼编码译码问题
哈夫曼编码和译码
右子 0 0 0 0 0 0 0 0 7 4 9 10 11 12 14
23 11 5
29 14 3 7 8
哈夫曼树的存储结构
9
1 2 3 4 5 6 7 8
0 1 0
1
1
0
1 1 1 0 0 1 1 0 1 1 0 0 0 0 1 1 1 0 1 0
哈夫曼编码
10
结点结构描述: 结点结构描述: typedef struct { float weight; /*数据域用于存放权值 ; 数据域用于存放权值 数据域用于存放权值*/ int lchild,parent,rchild;/*指针域 , 指针域*/ , ; 指针域 }htnode,*hufmtree; , ; typedef char * huffmancode; ; 其中,每个结点包含 个域 个域, 其中,每个结点包含4个域,weight域用于存放结点 域用于存放结点 的权值, 分别为结点的左, 的权值,lchild,rchild分别为结点的左,右孩子在一维 , 分别为结点的左 数组(或静态链表)中的下标, 数组(或静态链表)中的下标,parent是结点的双亲在 是结点的双亲在 一维数组中的下标加1. 一维数组中的下标加 .
难点
确定贪心选择标准,实现哈夫曼编译码器. 确定贪心选择标准,实现哈夫曼编译码器.
哈夫曼编码 假设每种字符在电文中出现的次数为wi, 假设每种字符在电文中出现的次数为 ,其编码 长度为li,电文中有n种字符 种字符, 长度为 ,电文中有 种字符,则电文总长度应为 n w1l1+w2l2+…+ wnln= ∑ w i l i .对应到二叉树上,n 对应到二叉树上, i =1 可以看作是二叉树中叶子结点的个数, 可以看作是二叉树中叶子结点的个数,wi可以看作是 叶子结点的权值, 恰为从根结点到叶子结点K 叶子结点的权值,li恰为从根结点到叶子结点 i的路 径长度,显然, 径长度,显然,设计电文总长度最短的二进制前缀 编码即是构造以字符出现频率作为权值的具有n个叶 编码即是构造以字符出现频率作为权值的具有 个叶 子结点的哈夫曼树, 子结点的哈夫曼树,由此所得到的二进制前缀编码 称为哈夫曼编码( 称为哈夫曼编码(Huffman Code). ).
哈夫曼编码的解码过程
哈夫曼编码的解码过程
哈夫曼编码是一种被广泛应用于数据压缩领域的编码算法。它通过
构建一棵特殊的二叉树来实现对源数据的编码和解码。在编码过程中,哈夫曼编码根据源数据的频率分配较短的编码给出现频率较高的字符,相反地,给出现频率较低的字符分配较长的编码,从而有效地减小编
码后的数据长度。而解码过程则是将编码后的数据转换为原始数据的
过程。
一、哈夫曼编码的基本原理
哈夫曼编码的基本原理是根据字符出现的频率来构建一棵哈夫曼树,以实现对字符的编码和解码。具体步骤如下:
1. 统计字符的频率:首先,需要对待编码的源数据进行扫描,并统
计每个字符的出现频率。通常可以使用哈希表等数据结构来记录字符
及其对应的频率。
2. 构建哈夫曼树:根据字符的频率,构建一棵哈夫曼树。构建哈夫
曼树的算法可以采用贪心策略,即每次选择频率最小的两个节点合并,直到所有节点合并完毕,最终形成哈夫曼树。
3. 生成编码表:按照哈夫曼树的结构,为每个字符生成对应的编码。从哈夫曼树的根节点开始,向左子树路径走一步表示编码位为0,向右子树路径走一步表示编码位为1,直到叶子节点,即可得到该字符的编码。编码表可以使用哈希表等数据结构来存储字符和对应的编码。
4. 进行编码:将待编码的源数据字符根据编码表进行编码,生成对
应的哈夫曼编码序列。编码后的数据长度通常会显著减小,实现数据
的压缩。
二、哈夫曼编码的解码过程
哈夫曼编码的解码过程是将编码后的数据序列转换回原始数据的过程。具体步骤如下:
1. 读取编码序列:从编码后的数据中逐个读取编码位,直到读取到
一个有效的编码。
哈夫曼树的编码和解码
哈夫曼树的编码和解码是哈夫曼编码算法的重要部分,下面简要介绍其步骤:
1. 编码:
哈夫曼编码是一种变长编码方式,对于出现频率高的字符使用较短的编码,而对于出现频率低的字符使用较长的编码。具体步骤如下:(1)根据字符出现的频率,构建哈夫曼树。频率相同的字符,按照它们在文件中的出现顺序排列。
(2)从哈夫曼树的叶子节点开始,从下往上逐步进行编码。对于每个节点,如果该节点有左孩子,那么左孩子的字符编码为0,右孩子的字符编码为1。如果该节点是叶子节点,则该节点的字符就是它的编码。
(3)对于哈夫曼树中的每个节点,都记录下它的左孩子和右孩子的位置,以便后续的解码操作。
2. 解码:
解码过程与编码过程相反,具体步骤如下:
(1)从哈夫曼树的根节点开始,沿着路径向下遍历树,直到找到一个终止节点(叶节点)。
(2)根据终止节点的位置信息,找到对应的字符。
(3)重复上述步骤,直到遍历完整个编码序列。
需要注意的是,哈夫曼编码是一种无损压缩算法,解压缩后的数据与原始数据完全相同。此外,由于哈夫曼编码是一种变长编码方式,因此在解码时需要从根节点开始逐个解码,直到解码完成。
哈夫曼树编码译码实验报告
数据结构课程设计设计题目:哈夫曼树编码译码
课题名称
院系
学号姓名哈夫曼树编码译码
年级专业
成绩
1、课题设计目的:
在当今信息爆炸时代,如何采用有效的数据压缩技术节省数据文件的存储空间和计算机网络的传送时间已越来越引起人们的重视,哈夫曼编码正是一种应用广泛且非常有效的数据压缩技术。哈夫曼编码是一种编码方式,以哈夫曼树—即最优二叉树,带权路径长度最小的二叉树,时常应用于数据压缩。哈弗曼编码使用一张特殊的编码表将源字符(例如某文件中的一个符号)进行编码。这张编码表的特殊之处在于,它是根据每一个源字符浮现的估算概率而建立起来的。
课题设计目的与设计意义2、课题设计意义:
哈夫曼编码的应用很广泛,利用哈夫曼树求得的用于通信的二进制编码称为哈夫曼编码。树中从根到每一个叶子都有一条路径,对路径上的各分支约定:指向左子树的分支表示“0”码,指向右子树的分支表示“1”码,取每条路径上的“0”或者“1”的序列作为和各个叶子对应的字符的编码,这就是哈夫曼编码。哈弗曼译码输入字符串可以把它编译成二进制代码,输入二进制代码时可以编译成字符
串。
指导教师:
年月日
第一章需求分析 (1)
第二章设计要求 (1)
第三章概要设计 (2)
(1)其主要流程图如图 1-1 所示。 (3)
(2)设计包含的几个方面 (4)
第四章详细设计 (4)
(1)①哈夫曼树的存储结构描述为: (4)
(2)哈弗曼编码 (5)
(3)哈弗曼译码 (7)
(4)主函数 (8)
(5)显示部份源程序: (8)
第五章调试结果 (10)
第六章心得体味 (12)
第七章参考文献 (12)
哈夫曼编码解码
Huffman编/解码
一.问题描述
1.题目内容:利用Huffman编码进行通信可以大大提高信道的利用率,缩短信息传输时间,降低传输成本。但是,这要求在发送端通过一个编码系统对待传数据进行预先编码,在接收端进行解码。对于双工信道(即可以双向传输信息的信道),每端都需要一个完整的编/解码系统。
2.基本要求:一个完整的系统应该具有以下功能:
1. I:初始化(Initialization)。从终端读入字符集大小n,以及n 个字符和n个权值,建立Huffman树,并将它存入hfmTree中。
2. E:编码(Encoding)。利用已经建好的Huffman树(如果不在内存,则应从文件hfmTree中读取),对文件ToBeTran中的正文进行编码,然后将结果存入文件CodeFile中。
3. D:解码(Decoding)。利用已经建立好的Huffman树将文件CodeFile中的代码进行解码,结果存入TextFile中。
4. P:打印代码文件(Print)。将文件CodeFile以紧凑的格式显示在终端上,每行50个代码。同时将此字符形式的编码文件写入文件CodePrint中。
5. T:打印Huffman树(Tree Printing)。将已经在内存中的Huffman树以直观的形式(凹入的形式)显示在终端上,同时将此字符形式的Huffman树写入文件TreePrint中。
数据机构实验报告
3.测试数据:
用下表给出的字符集和频度的实际统计数据建立Huffman树,并对以下报文进行编码和译码:“THIS PROGRAM IS MY FAVORITE”。
哈夫曼编码译码
题目:哈夫曼编码/译码
班级:电气八班姓名:辛凤来学号:2012484111
完成日期:2013.11.4
一、需求分析
利用哈夫曼编码进行通信可以大大提高信道利用率,缩短信息传输时间,降低传输成本。但是,这要求在发送端通过一个编码系统对待传数据预先编码,在接收端将传来的数据进行译码(复原)。对于双工信道(即可以双向传输信息的信道),每端都需要一个完整的编/译码系统。试为这样的信息收发编写一个哈夫曼码的编/译码系统。
二、程序的模块结构
(1)主程序模块:
Int main(){
初始化;
While(“命令”=“退出”)
{ 接受命令;
处理命令;
}
}
(2)、建树模块——实现定义的抽象数据类型
(3)、编/译码模块——实现字符串的编/译码
三、祥细设计
(1)分析需求,分析功能模块,并将每个功能模块分配给自己的组员进行能够分工协
(2)首先定义了函数的数据类型如下:
typedef struct{
unsigned int weight;//字符对应的权值
unsigned int parent,lchild,rchild;
}HTNode,*HuffmanTree;//此处定义了哈夫曼树节点的数据类型。提供给Huffman使用
typedef struct{
HuffmanTree HT;
char *c;//存放将要建立哈夫曼树的字符
int longth;//字符的大小,即开始第一步输入的一个整数
HuffmanCode HC;//存放对应的哈夫编码即对应的01代码
}Huffman;
(4)其次实设计的建立哈夫满曼树的函数功能函数。
哈夫曼编码译码器实验报告
哈夫曼编码译码器实验报告
实验名称:哈夫曼编码译码器实验
一、实验目的:
1.了解哈夫曼编码的原理和应用。
2.实现一个哈夫曼编码的编码和译码器。
3.掌握哈夫曼编码的编码和译码过程。
二、实验原理:
哈夫曼编码是一种常用的可变长度编码,用于将字符映射到二进制编码。根据字符出现的频率,建立一个哈夫曼树,出现频率高的字符编码短,出现频率低的字符编码长。编码过程中,根据已建立的哈夫曼树,将字符
替换为对应的二进制编码。译码过程中,根据已建立的哈夫曼树,将二进
制编码替换为对应的字符。
三、实验步骤:
1.构建一个哈夫曼树,根据字符出现的频率排序。频率高的字符在左
子树,频率低的字符在右子树。
2.根据建立的哈夫曼树,生成字符对应的编码表,包括字符和对应的
二进制编码。
3.输入一个字符串,根据编码表将字符串编码为二进制序列。
4.输入一个二进制序列,根据编码表将二进制序列译码为字符串。
5.比较编码前后字符串的内容,确保译码正确性。
四、实验结果:
1.构建哈夫曼树:
-字符出现频率:A(2),B(5),C(1),D(3),E(1) -构建的哈夫曼树如下:
12
/\
/\
69
/\/\
3345
/\/\/\/\
ABCDE
2.生成编码表:
-A:00
-B:01
-C:100
-D:101
-E:110
3.编码过程:
4.译码过程:
5.比较编码前后字符串的内容,结果正确。
五、实验总结:
通过本次实验,我了解了哈夫曼编码的原理和应用,并且实现了一个简单的哈夫曼编码的编码和译码器。在实验过程中,我充分运用了数据结构中的树的知识,构建了一个哈夫曼树,并生成了编码表。通过编码和译码过程,我进一步巩固了对树的遍历和节点查找的理解。实验结果表明,本次哈夫曼编码的编码和译码过程正确无误。
数据结构哈夫曼编码译码
赫夫曼编码/译码器
(1) 已知某系统在通信联络中只可能出现八种字符,其频率分别为
0.05,0.29,0.07,0.08,0.14,0.23,0.03,0.11,试设计赫夫曼编码。
(2) 用下表给出的字符集和频度的实际统计数据建立赫夫曼树,并实现以下报文的编码和译码:“THIS PROGRAME IS MY FA VORITE”。
字符 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
1.#include<iostream.h>
2.#include<stdio.h>
3.#include<stdlib.h>
4.#include<string.h>
5.#include<fstream.h>
6.typedef struct{ //赫夫曼树的结构体
7.char ch;
8.int weight; //权值
9.int parent,lchild,rchild;
10.}htnode,*hfmtree;
11.typedef char **hfmcode;
12.
13.void Select(hfmtree &HT,int a,int *p1,int *p2) //Select函数,选出HT树到a为止,权值最小且parent为0的2个节点
哈夫曼编码译码.
《数据结构》
课程设计报告
设计题目哈夫曼编码译码
学院名称信息工程学院
专业班级计算机科学与技术2班姓名
学号
摘要
Huffman编码是一种可变长编码方式,是二叉树的一种特殊转化形式。它的原理是:将使用次数多的代码转换成长度较短的编码,而使用次数少的可以使用较长的编码,并且保持编码的唯一可解性。本文根据Huffman编码原理,在详细设计中,根据权值和最小的根本原则,我们输入要编码的字符集及其它的权值,再根据在概要设计中提到的节点Node类,算法SuanFa类以及主类JieMian类,建立哈夫曼树,并进行编码,最后输出哈夫曼编码。
在完成Huffman编码后,我们利用其构建的哈夫曼编码树来进行译码。与编码过程不同,译码过程中,我们将用户输入的二进制代码串依次与字符集中的每个字符的编码进行比较,译出一个字符后,循环比较下一个字符的编码,直到所有二进制码全部译出为止。
在编码和译码的过程中,我们遇到很多问题,诸如算法、语法问题,但我们都通过不断的分析,和调试将这些问题一一解决,最终建立了一个完整的编/译码系统。
关键词:Huffman编码树;最优二叉树;编码;译码
Abstract
Huffman coding is a encoding of variable length and a special transformation form of the binary tree. Its principle is: the code that be used more often will be changed into the code of shorter lengths, while the codes that be used less often can be transformed into the code of longer lengths and the unique solution of coding will be kept. According to the theory of Huffman coding, firstly we enter the character set which will be used to coding and their weights. Secondly, according to the fundanmental principle that the sum of the weights needs to be the smallest , the program designs Huffman tree in accordance with these class which are initialized in the outline such as class Node,class SuanFa,and class JieMian. At last, the computer will output Huffman coding on user interface.
哈夫曼编码及其解码全过程
哈夫曼编码及其解码全过程
1.引言
1.1 概述
在这篇长文中,我们将介绍哈夫曼编码及其解码的全过程。哈夫曼编码是一种可变字长编码技术,它通过统计字符出现频率来构建编码表,使得出现频率高的字符使用较短的编码,出现频率低的字符使用较长的编码,从而实现高效的数据压缩。在本文中,我们将详细探讨哈夫曼编码的过程,包括哈夫曼树的构建和编码表的生成。此外,我们还将介绍哈夫曼解码的过程,包括解码表的生成和解码过程。最后,我们将总结哈夫曼编码及其解码,并展望其在实际应用中的前景。通过阅读本文,读者将全面了解哈夫曼编码及其解码的原理和实现方法。
【1.2 文章结构】
本文共分为三个部分,分别是引言、正文和结论。下面将对每个部分进行详细的说明。
(1) 引言部分包括三小节。首先是概述,将简要介绍哈夫曼编码及其解码的基本概念和作用。其次是文章结构,将列出本文的整体结构以及各个部分的内容。最后是目的,阐述撰写这篇长文的目标和意义。
(2) 正文部分是本文的核心部分,分为两个小节。第一个小节是哈夫曼编码过程,将详细介绍哈夫曼树的构建和编码表的生成过程。具体而言,将介绍如何根据字符的出现频率构建哈夫曼树,并通过遍历哈夫曼树生成对应的编码表。第二个小节是哈夫曼解码过程,将详细介绍解码表的生成和解码的具体步骤。具体而言,将介绍如何根据编码表构建解码表,并通
过解码表将编码还原成原始字符。
(3) 结论部分也包括两个小节。首先是总结,将对整篇文章的内容进行简要回顾,并总结哈夫曼编码及其解码的关键步骤和特点。其次是应用前景,将探讨哈夫曼编码在实际应用中的潜在价值和发展前景,展示其在数据压缩和信息传输等领域的重要性。
哈夫曼编码译码器数据结构C语言
一、需求分析
目前,进行快速远距离通信的主要手段是电报,即将需传送的文字转化成由二级制的字符组成的字符串.例如,假设需传送的电文为“ABACCDA",它只有4种字符,只需两个字符的串,便可以分辨。假设A 、B 、C 、D 、的编码分别为00,01,10和11,则上述7个字符的电文便为“00010010101100”,总长14位,对方接受时,可按二位一分进行译码。
当然,在传送电文时,希望总长尽可能地短.如果对每个字符设计长度不等的编码,且让电文中出现次数较多的字符采用尽可能短的编码,则传送电文的总长便可减少。如果设计A 、B 、C 、D 的编码分别为0,00,1,01,则上述7个字符的电文可转换成总长为9的字符串“000011010"。但是,这样的电文无法翻译,例如传送过去的字符串中前4个字符的字串“0000”就可以有很多种译法,或是“AAAA ”或者“BB ”,或者“ABA ”等.因此,若要设计长短不等的编码,则必须是任一字符的编码都不是另一个字符的编码的前缀,这种编码称作前缀编码。
然而,如何进行前缀编码就是利用哈夫曼树来做,也就有了现在的哈夫曼编码和译码.
二、概要设计
利用哈夫曼树编/译码 (一)、建立哈夫曼树 (二)、对哈夫曼树进行编码 (三)、输出对应字符的编码 (四)、译码过程
主要代码实现: struct code //结构体的定义 { char a ; int w ; int parent; int lchild; int rchild; };
void creation(code *p,int n ,int m ); //建立哈夫曼树 void coding (code *p,int n ); //编码 void display (code *p ,int n ,int m); //输出函数 void translate (char **hc,code *p,int n); //译码
简述哈夫曼编码译码过程
简述哈夫曼编码译码过程
哈夫曼编码是一种用于数据压缩的无损编码方法,它基于字符出现频率的统计信息,将频率较高的字符用较短的二进制编码表示,而将频率较低的字符用较长的二进制编码表示。在对数据进行解码时,需要使用相同的编码表来将编码转换回原始数据。
哈夫曼编码的过程可以分为两个主要步骤:构建哈夫曼树和生成编码表。下面将详细介绍每个步骤的实现过程。
构建哈夫曼树:
1. 统计字符的频率:遍历要编码的数据,统计每个字符出现的频率。
2. 创建叶节点列表:将每个字符及其频率作为一个叶节点,构建一个列表。
3. 构建哈夫曼树:重复执行以下操作,直到只剩下一个节点:
a. 从叶节点列表中选择两个频率最低的节点作为左右子节点。
b. 创建一个新的节点,其频率为左右子节点频率之和,并将其设为左右子节点的父节点。
c. 将新的父节点添加到叶节点列表中。
d. 从叶节点列表中删除选择的两个节点。
4. 哈夫曼树的根节点即为构建完成的树。
生成编码表:
1. 遍历哈夫曼树:从根节点开始,遍历哈夫曼树的每个节点。
a. 若当前节点为叶节点,记录该节点所表示字符的编码路径。
b. 若当前节点有左子节点,将路径标记为0,并继续遍历左子节点。
c. 若当前节点有右子节点,将路径标记为1,并继续遍历右子节点。
2. 将每个字符与其对应的编码路径关系保存在编码表中。
哈夫曼编码的过程中,编码表的生成是非常重要的一步。通过遍历哈夫曼树,可以确定每个字符的唯一编码,从而在进行译码时能够将编码路径按照对应的编码表转换为原始数据。
译码过程:
1. 读取编码数据:将压缩后的二进制数据按位读取。
数据结构 哈夫曼编码与译码
数据结构哈夫曼编码与译码
哈夫曼编码与译码是数据结构中的重要概念,它是一种可变长度编码的方法,
用于压缩数据。在本文中,我将详细介绍哈夫曼编码与译码的原理、步骤以及应用。
一、哈夫曼编码的原理
哈夫曼编码是一种根据字符出现的频率来构建编码表的方法,使得频率较高的
字符使用较短的编码,频率较低的字符使用较长的编码。这样可以有效地减少数据的存储空间。
二、哈夫曼编码的步骤
1. 统计字符频率:遍历待编码的文本,统计每个字符出现的频率。
2. 构建哈夫曼树:根据字符频率构建哈夫曼树。首先将每个字符作为一个独立
的树节点,然后合并频率最低的两个节点,生成一个新的节点,频率为这两个节点的频率之和。重复此过程,直到所有节点都合并为一个根节点,得到哈夫曼树。
3. 生成编码表:从根节点开始遍历哈夫曼树,左子树路径为0,右子树路径为1,将路径上的0和1依次添加到对应字符的编码中,得到编码表。
4. 进行编码:根据编码表,将待编码的文本中的每个字符替换为对应的编码。
5. 完成编码:得到编码后的文本。
三、哈夫曼译码的步骤
1. 根据编码表,将编码后的文本逐个字符地进行译码。从根节点开始,根据字
符是0还是1,选择左子树或右子树进行下一步操作。
2. 如果到达叶子节点,则找到对应的字符,并将该字符添加到译码结果中。
3. 重复上述步骤,直到译码结束,得到原始文本。
四、哈夫曼编码与译码的应用
哈夫曼编码与译码广泛应用于数据压缩领域。通过使用哈夫曼编码,可以大大减小数据的存储空间,提高数据传输的效率。在图像、音频、视频等大数据文件的传输和存储中,哈夫曼编码被广泛使用。
哈夫曼编码译码
哈夫曼编码译码
哈夫曼编码译码
编码与译码是信息传输的两个基本环节,哈夫曼编码是一种基于数据
压缩的编码方式,能够有效减小数据传输时所需的带宽和存储空间,
广泛应用于图像、音频、视频等大数据的传输和存储中。本文将从哈
夫曼编码的定义、算法及其应用等三个方面进行探讨。
一、哈夫曼编码的定义
哈夫曼编码,又称为变长编码或最优编码,是一种通过树形结构来实
现数据压缩的编码方式。其算法的基本思想是:对于频率高的字符,
分配较短的编码;对于频率低的字符,分配较长的编码。这样,可以
减小数据传输时所需要的带宽和存储空间。
二、哈夫曼编码的算法
哈夫曼编码的算法分为两个步骤:建立哈夫曼树和生成编码。
1. 建立哈夫曼树:首先将每个字符看作独立的一个节点,然后根据字
符出现的频率来构建哈夫曼树。具体的方法是:对于给定的一组字符,计算其出现的频率,并将其按照频率的大小进行排序。然后将频率最
小的两个字符合并为一个节点,该节点的频率为两个字符的频率之和,并将该节点插入到集合中。重复此过程,直到集合中只剩下一个节点,
即构建出了哈夫曼树。
2. 生成编码:从根节点开始,遍历树的所有节点(左子树编码为0,右子树编码为1),并记录所有节点对应的字符编码。这样,每个字符就可以表示为一串01序列,其中该序列的长度越小,表示该字符在原数
据中出现的频率越高。
三、哈夫曼编码的应用
哈夫曼编码在数据压缩、网络传输、存储优化等领域都有广泛的应用。
1. 数据压缩:哈夫曼编码可将文件的体积减小到原来的三分之一左右,从而有效地减小文件的传输和存储所需要的空间。
2. 网络传输:在网络传输中,带宽和传输速率是非常宝贵的资源。哈
哈夫曼译码原理
哈夫曼译码原理
一、引言
哈夫曼编码是计算机科学中非常重要的一种压缩算法,它最早由美国数学家大卫·哈夫曼(David A. Huffman)在1952年发明。哈夫曼编码的核心理念就是通过使用不等长编码,来减少重复信息所占用的比特数。针对哈夫曼编码算法,译码是其不可或缺的一个关键部分。本文主要介绍哈夫曼编码中的译码原理及其实现。
二、哈夫曼编码简介
哈夫曼编码是一种前缀编码,即一个字符的编码不会是另一个字符编码的前缀。这个约束条件使得译码的效率非常高。使用哈夫曼编码算法,我们可以生成一个字符集中所有字符的编码表,以便于我们将其压缩为更小的文件。相较于其他的压缩算法,这种方法具有更好的效果,节省更多的存储空间。
三、哈夫曼译码原理
在哈夫曼编码算法中,译码的过程就是将经过编码的比特流再次转化为原本的字符形式。哈夫曼编码的编码表是由每个字符的编码和其出现频率所组合而成的。
当我们获取到进行解码的比特流后,我们开始首先从根节点开始,逐
个读取比特。如果读取到的比特是0,我们就继续向左走;如果读取到的比特是1,我们就向右走。我们一边按照这种方式遍历哈夫曼树,一边将遇到的路径中涉及的字符记录下来,这样我们就可以得到经过编
码的字符。
通常情况下,为了识别整个编码序列的末尾,我们在编码序列(叶子
节点)的末尾添加了一个特殊的“结束字符”,用来指示解码过程结束。
四、哈夫曼译码的实现
现在我们来看一下哈夫曼解码的具体实现。首先,我们需要遵循以下
步骤:
1.输入一个压缩过的文件;
2.读取并解压文件的头部信息,提取出哈夫曼编码表;
哈夫曼编码和译码系统(附源代码)
题目:哈夫曼编码和译码系统院系:
专业:
姓名:
学号:
指导教师:
日期:
实训报告
目录
一.需求分析 (2)
二.概要设计
(1)建立哈夫曼树、编码 (3)
(2)字符匹配 (3)
(3)哈夫曼树遍历 (3)
三.详细设计及编码实现 (3)
四.流程图
(1)总流程图 (15)
(2)编码实现流程图 (16)
(3)译码实现流程图 (17)
五.调试分析
(1)计算权值 (18)
(1)生成哈夫曼树,建立编码表 (18)
(3)将输入字符编码 (19)
(4)输入新的字符串,进行译码 (19)
(5)输入新的二进制数将其译为字符 (20)
六. 系统维护 (20)
七.实验总结 (20)
八. 源代码 (21)
一.需求分析
《1》问题描述:在传送电文时,人们总是希望传送时间尽可能短,这就是要求使电文代码长度尽可能短。利用哈夫曼编码进行通信可以大大提高信道利用率,缩短信息传输时间,降低传输成本。但是,这要求在发送端通过一个编码系统能够对待传输数据预先编码,在接收端将传来的数据进行译码。对于双工信道(即可以双向传输信息的信道),每段都需要一个完整的编/译系统。所以为这样的信息收发站写一个哈夫曼的编译码系统。
《2》打开一篇英文文章,统计该文章中每个字符出现的次数,然后以它们作为权值,对每一个字符进行编码,编码完成后再对其编码进行译码。
问题补充:
1. 从硬盘的一个文件里读出一段英语文章。
2. 统计这篇文章中的每个字符出现的次数。
3. 以字符出现字数作为权值,构建哈夫曼树,并将哈夫曼树的存储结构的初态和终态进行输出。
4. 对每个字符进行编码并将所编码写入文件然后对所编码进行编译。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
《数据结构》课程设计报告题目——哈夫曼编码译码问题
班级:
学号:
姓名:
时间:
一、设计目的与内容
1.设计目的
熟悉对哈夫曼编码的应用以及构造方法,熟悉对树的存储方式的应用。
2.设计内容:
任务:利用哈夫曼编码进行通信可以大大提高信道利用率,缩短信息传输时间,降低传输成本,但是,这要求在发送端通过一个编码系统对待传数据预先编码,在接收端将传来的数据进行译码(复原)。对于双工信道(即可以双向传输信息的信道),每端都需要一个完整的编/译码系统。试为这样的信息收发站写一哈夫曼编/译码系统。
要求:
1)初始化:从终端输入字符集的大小n,以及n个字符和n个权值,建立哈夫曼树。
2)输出哈夫曼树,及各字符对应的编码。
3)编码:利用建好的哈夫曼树,对输入的待发送电文进行编码。同时输入原文及编码串。4)译码:利用建好的哈夫曼树,对输入的已接收电文进行译码。同时输入编码串及原文。
二、算法的基本思想
算法的主要思路是:
(1)定义结构体存储赫夫曼树的结点类型
(2)定义函数strcpy(char *S1,char *S2)将字符串S2复制到S1
(3)定义函数Select(HuffmanTree HT,int t,int &s1,int &s2)在HT[1]到HT[t-1]中找出权值最小的两个S1和S2
(4)定义函数HuffmanCoding( HuffmanTree &HT,HuffmanCode &HC,int *w,int n)根据各个字符的权值构造赫夫曼树HT,将对应的赫夫曼编码存储在HC中
(5)定义函数InitHuff_T( HuffmanTree &HT, HuffmanCode &HC, char ch[],int &n )初始化赫夫曼数,要求用户输入字符和相应权值
(6)定义函数Encoding(HuffmanTree &HT, HuffmanCode &HC, char ch[])根据赫夫曼编码将用户指定的文件中的字符编成相应的编码,并将所得编码存储到用户指定文件
(7)定义函数Decoding(HuffmanTree HT, char ch[] , int n)对指定的存储由赫夫曼编码表示的信息的文件进行译码,翻译成相应的字符表示,并存储到指定文件
(8)定义函数ReadHuff_T( HuffmanTree &HT, HuffmanCode &HC, char ch[], int &n)从文件读取赫夫曼树
(9)定义主函数main()实现相应的功能
三、测试数据
首先运行程序:
请输入你要选择的功能
1.初始化
2.编码
3.译码
4.退出
1
请输入编码字符集的大小n:4
请输入第1个字符和该字符的权值w:a1
请输入第2个字符和该字符的权值w:b3
请输入第3个字符和该字符的权值w:c2
请输入第4个字符和该字符的权值w:d6
4
a 110
b 10
c 111
d 0
请输入你要选择的功能
1.初始化
2.编码
3.译码
4.退出
这时在工程目录下建立文件a.txt,内容为:abcda
继续执行程序
2
请输入所要进行编码的文件的文件名:a.txt
请输入编码后编码表示的信息所存储到的文件的文件名:c.txt
110101110110字符
无法识别,程序将退出。
Press any key to continue
此时c.txt文件下的内容为:110101110110
这时我们将c.txt重命名为CodeFile
请输入你要选择的功能
1.初始化
2.编码
3.译码
4.退出
3
请输入所要译的文件名:CodeFile
请输入译后的字符存储到的文件的文件名:1.txt
abcda
此时文件1.txt的内容为:abcda
四、源程序及系统文件使用说明
#include
#include
#define Yes 1 //当程序已经调用过初始化赫夫曼树的InitHuff_T()函数,或已从htfTree文件读取过,则将Init_Mode置为Yes,否则为No
#define No 0
typedef struct {
unsigned int weight;
unsigned int parent,lchild,rchild;
}HTNode, * HuffmanTree; //存储赫夫曼树的结点类型
typedef char * * HuffmanCode; //用于存储字符集中各个字符相应的赫夫曼编码
void strcpy(char *S1,char *S2){ //将字符串S2复制到S1
int i = 0;
while( S2[i] != '\0' ){
S1[i] = S2[i];
i++;
}
S1[i] = '\0';
}
void Select(HuffmanTree HT,int t,int &s1,int &s2){ //在HT[1]到HT[t-1]中找出权值最小的两个S1和S2
int i = 1;
s1 = s2 = 0;
HT[0].weight = 65535;
while( i <= t ){ //遍历查找权值最小的结点S1
if( HT[i].parent == 0 && HT[i].weight < HT[s1].weight )
s1 = i;
i++;
}
i = 1;
while( i <= t ){ //遍历查找除S1外权值最小的结点S2
if( i != s1 && HT[i].parent == 0 && HT[i].weight < HT[s2].weight )
s2 = i;
i++;
}
}
int HuffmanCoding( HuffmanTree &HT,HuffmanCode &HC,int *w,int n){ //根据各个字符的权值构造赫夫曼树HT,将对应的赫夫曼编码存储在HC中
int s1,s2,m,i,start;
unsigned int c,f;
HTNode * p;
char *cd;
if( n <= 1 ) return 0;
m = 2 * n - 1; //赫夫曼树的总结点树为m
HT = (HuffmanTree)malloc((m + 1) * sizeof(HTNode)); //申请存储赫夫曼树的空间
for(p = HT + 1, i = 1; i <= n; ++i, ++p, ++w){ //将各个叶子结点的weight赋以相应的权值,