基于哈夫曼编码的通信系统的设计与实现
电报哈夫曼树课程设计

电报哈夫曼树课程设计一、课程目标知识目标:1. 学生能理解哈夫曼树的定义及其在数据压缩中的应用。
2. 学生能掌握哈夫曼编码的构建过程,并运用其进行基本的编码和解码操作。
3. 学生能了解哈夫曼树的基本性质,如最优二叉树、路径长度最短等。
技能目标:1. 学生能够运用所学知识解决实际问题,如使用哈夫曼编码进行文件压缩和解压缩。
2. 学生通过实际操作,培养解决问题的能力,提高逻辑思维能力。
3. 学生能够运用数学方法,对哈夫曼树进行证明和分析。
情感态度价值观目标:1. 学生培养对数据结构和算法的兴趣,认识到其在实际生活中的重要性。
2. 学生通过合作学习,培养团队协作精神,提高沟通与表达能力。
3. 学生在学习过程中,培养面对困难勇于挑战的精神,增强自信心。
课程性质:本课程为信息技术或计算机科学相关学科的课程,旨在通过哈夫曼树的学习,让学生掌握数据压缩的基本原理和方法。
学生特点:考虑到学生所在年级的特点,课程设计将结合具体实例,由浅入深地进行教学,使学生易于理解和掌握。
教学要求:教学过程中,注重理论与实践相结合,强调学生的实际操作能力。
同时,注重培养学生的逻辑思维能力和团队协作能力,提高学生的综合素质。
通过分解课程目标,为后续教学设计和评估提供明确的方向。
二、教学内容1. 引入:介绍数据压缩的概念及其在生活中的应用,引导学生思考数据压缩的必要性。
2. 哈夫曼树基本概念:讲解哈夫曼树的定义、性质和应用场景,使学生了解哈夫曼树在数据压缩中的重要性。
- 理解哈夫曼树的构建过程- 掌握哈夫曼树的路径长度和最优二叉树的概念3. 哈夫曼编码:详细讲解哈夫曼编码的构建方法,以及如何利用哈夫曼编码进行数据压缩和解压缩。
- 学习哈夫曼编码的构建步骤- 实践哈夫曼编码的应用案例4. 哈夫曼树的分析与证明:分析哈夫曼树的基本性质,并对最优二叉树进行数学证明。
- 掌握哈夫曼树的数学证明方法- 理解哈夫曼树在数据压缩中的优势5. 实践操作:结合教材实例,让学生动手实践,加深对哈夫曼树及其编码方法的理解。
信源编码的基本原理及其应用

信源编码的基本原理及其应用课程名称通信原理Ⅱ专业通信工程班级*******学号******学生姓名*****论文成绩指导教师***********信源编码的基本原理及其应用信息论的理论定义是由当代伟大的数学家美国贝尔实验室杰出的科学家香农在他1948 年的著名论文《通信的数学理论》所定义的,它为信息论奠定了理论基础。
后来其他科学家,如哈特莱、维纳、朗格等人又对信息理论作出了更加深入的探讨。
使得信息论到现在形成了一套比较完整的理论体系。
信息通过信道传输到信宿的过程即为通信,通信中的基本问题是如何快速、准确地传送信息。
要做到既不失真又快速地通信,需要解决两个问题:一是不失真或允许一定的失真条件下,如何提高信息传输速度(如何用尽可能少的符号来传送信源信息);二是在信道受到干扰的情况下,如何增加信号的抗干扰能力,同时又使得信息传输率最大(如何尽可能地提高信息传输的可靠性)。
这样就对信源的编码有了要求,如何通过对信源的编码来实现呢?通常对于一个数字通信系统而言,信源编码位于从信源到信宿的整个传输链路中的第一个环节,其基本目地就是压缩信源产生的冗余信息,降低传递这些不必要的信息的开销,从而提高整个传输链路的有效性。
在这个过程中,对冗余信息的界定和处理是信源编码的核心问题,那么首先需要对这些冗余信息的来源进行分析,接下来才能够根据这些冗余信息的不同特点设计和采取相应的压缩处理技术进行高效的信源编码。
简言之,信息的冗余来自两个主要的方面:首先是信源的相关性和记忆性。
这类降低信源相关性和记忆性编码的典型例子有预测编码、变换编码等;其次是信宿对信源失真具有一定的容忍程度。
这类编码的直接应用有很大一部分是在对模拟信源的量化上,或连续信源的限失真编码。
可以把信源编码看成是在有效性和传递性的信息完整性(质量)之间的一种折中有段。
信源编码的基本原理:信息论的创始人香农将信源输出的平均信息量定义为单消息(符号)离散信源的信息熵:香农称信源输出的一个符号所含的平均信息量为 为信源的信息熵。
电力系统通信中数据压缩技术的运用

电力系统通信中数据压缩技术的运用摘?要随着现代信息技术的高速发展,尤其现在用户对电能的大力需求,每天采集的数据量也是相当大,这些数据如果不经过处理就进行采集传给中央控制中心,将需要很大的带宽来进行传输而造成带宽拥挤。
由于现代数据压缩处理技术的快速发展,很快这一技术在电力通信系统中得到了应用,并解决了带宽的问题。
本文主要介绍了数据压缩技术的原理及分类,并指出电力系统通信中数据压缩技术的实现方法及设计原理,仅供学习和参考。
关键词电力通信;电力数据;数据处理;数据压缩技术;数据压缩方法中图分类号 tn915 文献标识码 a 文章编号1673-9671-(2012)052-0160-01随着现代计算机处理技术与通信技术的快速发展,最初的信息传输方式已经远远不能满足电力系统通信的传输,人们开始探究其他的技术应用,其中数据压缩技术的发展很快在电力系统通信的领域中崭露头角,这种技术的应用不仅给电力通信的传输带来了革命性的改变,而且现在各种压缩算法也存在差异,所以要想在应用中得到良好的综合压缩性能,还是必须针对各种因素进行比较分析而确定哪一种算法适合在电力系统通信中的应用。
1 数据压缩的原理数据压缩不仅要求降低数字化的信息冗余,而且还要能保证信号的质量。
数据压缩技术主要是依据信号源的特征及特性来进行处理,其中必须拥有三个方面的特性才能进行数据压缩处理。
1)信息量。
并不是所有的信号都需要进行压缩处理,一般针对于占用空间较大的数据才采用这一技术处理来完成所需要的转换过程。
主要将占用空间较大的数据进行切块压缩编码,到最后处理占用较少的带宽而完成数据的传输,不仅保证了信号的质量还提高了系统的稳定性。
2)冗余度。
若信号源的实际熵小于信号源编码的熵,那么这种信号源中存在冗余度,冗余度包括时间冗余、空间冗余、视觉冗余和听觉冗余等等。
压缩技术就是利用这些冗余量,将信号整合得到一种占用较小的空间里,而满足用户的更多需求。
3)编码模型。
哈夫曼编码解码

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”。
二.需求分析1. 编码结果以文本的方式存储在文件CodeFile中。
2. 用户界面可以设计为“菜单”方式:显示上述功能符号,再加上“Q”,表示退出(quit)。
请用户键入一个选择功能符。
此功能执行完毕后再显示此菜单,直至某次用户选择了Q为止。
3. 在程序的一次执行过程中,第一次执行I,D,C命令后,Huffman 树已经存在在内存中了,不必再读入。
定长编码与哈夫曼编码

定长编码与哈夫曼编码一、定长编码1.1 定长编码的定义和特点定长编码是一种将每个符号用固定长度的二进制代码表示的编码方式。
在定长编码中,每个符号的编码长度是固定的,不同的符号有不同的编码。
定长编码的特点包括:•每个符号的编码长度是相等的。
•不同的符号有不同的编码,因此可以唯一地解码出原始符号。
•编码长度固定,不依赖于符号的出现频率。
1.2 定长编码的应用和优缺点定长编码广泛应用于各种领域,例如通信、数据存储和信息传输等。
定长编码的主要优点和缺点如下:1.2.1 优点•简单易实现:定长编码的编解码过程简单,实现起来相对容易。
•解码效率高:由于每个符号的编码长度是固定的,解码时无需考虑编码长度的变化,因此解码效率较高。
•适用于等概率符号:对于每个符号出现的概率相等的情况,定长编码是一种很好的编码方式。
1.2.2 缺点•无法充分利用信息的统计特性:定长编码无法根据符号的出现频率来灵活地确定编码长度,因此在处理非等概率符号时,会导致编码的冗余度较高。
•编码效率较低:由于编码长度固定,无法根据符号的出现频率进行适当的压缩,因此编码效率较低。
二、哈夫曼编码2.1 哈夫曼编码的定义和原理哈夫曼编码是一种根据符号出现的概率进行变长编码的方法。
在哈夫曼编码中,频率较高的符号用较短的编码表示,频率较低的符号用较长的编码表示,从而提高编码效率。
哈夫曼编码的原理包括:1.统计每个符号出现的频率。
2.构建哈夫曼树:根据符号频率构建一棵二叉树,频率较低的符号在树的底部,频率较高的符号在树的顶部。
3.分配编码:从根节点开始,对树中的每个节点进行编码,左节点为0,右节点为1。
对于叶子节点,将其路径上的编码连接起来即为该符号的编码。
2.2 哈夫曼编码的应用和优缺点哈夫曼编码被广泛应用于数据压缩和信息传输等领域。
哈夫曼编码的主要优点和缺点如下:2.2.1 优点•编码效率高:根据符号出现的概率,将频率较高的符号用较短的编码表示,频率较低的符号用较长的编码表示,从而提高了编码效率。
《信息论与编码》第5章哈夫曼编码

什么是哈夫曼编码方法
1952年由美国计算机科学家戴维· 哈夫曼先生提出 是一种数据压缩技术 该方法依据字符出现的概率进行编码 ,其基本思想为: 出现概率高的字符使用较短的编码 出现概率低的则使用较长的编码 使编码之后的码字的平均长度最短
哈夫曼编码方法
哈夫曼编码方法包含两个过程
哈夫曼编码方法包含两个过程
编码过程和译码过程
编码过程 译码过程
构建哈夫曼树 CreatHT(W,&HT)
输入是字符频度表W
表中记录的是原码报文中出现的不同符号个数和频率
输出是哈夫曼树HT
进行哈夫曼译码 HuffmanDecod(HT,CC,W,&OC)
输入的是哈夫曼树HT、代码报文CC和字符频度表W 输出的是原码报文OC
OC
输出OC 到哈夫曼译码系统之外 返回开头
字母a的编码为110 字母n的编码为111
1
4 n
因此,在电文中出现频率 高的字母的编码相对短, 而出现频率低的字母的编 码相对长
111 字符编码表HC=((d,0),(i,10),(a,110),(n,111))
哈夫曼编码过程演示
编码 A1 A2 A3 0.23 0.21 0.18
1
0 1 0 1 0.10 0
编码过程和译码过程
编码过程
构建哈夫曼树 CreatHT(W,&HT)
输入是字符频度表W
表中记录的是原码报文中出现的不同符号个数和频率
输出是哈夫曼树HT
进行哈夫曼编码 HuffmanCoding(HT,&HC)
输入是哈夫曼树HT 输出是字符编码表HC
信息论与编码实验报告
信息论与编码实验报告一、实验目的信息论与编码是一门涉及信息的度量、传输和处理的学科,通过实验,旨在深入理解信息论的基本概念和编码原理,掌握常见的编码方法及其性能评估,提高对信息处理和通信系统的分析与设计能力。
二、实验原理(一)信息论基础信息熵是信息论中用于度量信息量的重要概念。
对于一个离散随机变量 X,其概率分布为 P(X) ={p(x1), p(x2),, p(xn)},则信息熵H(X) 的定义为:H(X) =∑p(xi)log2(p(xi))。
(二)编码原理1、无失真信源编码:通过去除信源中的冗余信息,实现用尽可能少的比特数来表示信源符号,常见的方法有香农编码、哈夫曼编码等。
2、有噪信道编码:为了提高信息在有噪声信道中传输的可靠性,通过添加冗余信息进行纠错编码,如线性分组码、卷积码等。
三、实验内容及步骤(一)信息熵的计算1、生成一个离散信源,例如信源符号集为{A, B, C, D},对应的概率分布为{02, 03, 01, 04}。
2、根据信息熵的定义,使用编程语言计算该信源的信息熵。
(二)香农编码1、按照香农编码的步骤,首先计算信源符号的概率,并根据概率计算每个符号的编码长度。
2、确定编码值,生成香农编码表。
(三)哈夫曼编码1、构建哈夫曼树,根据信源符号的概率确定树的结构。
2、为每个信源符号分配编码,生成哈夫曼编码表。
(四)线性分组码1、选择一种线性分组码,如(7, 4)汉明码。
2、生成编码矩阵,对输入信息进行编码。
3、在接收端进行纠错译码。
四、实验结果与分析(一)信息熵计算结果对于上述生成的离散信源,计算得到的信息熵约为 184 比特/符号。
这表明该信源存在一定的不确定性,需要一定的信息量来准确描述。
(二)香农编码结果香农编码表如下:|信源符号|概率|编码长度|编码值|||||||A|02|232|00||B|03|174|10||C|01|332|110||D|04|132|111|香农编码的平均码长较长,编码效率相对较低。
统计信源熵与哈夫曼编码
信息论与编码课程设计 1 信息论与编码课程设计报告
设计题目:统计信源熵与哈夫曼编码 专业班级 学 号 学生姓名 指导教师 教师评分
2015年 3 月 25 日 信息论与编码课程设计
2 目 录
一、设计任务与要求.................................................................................................................3 二、设计思路.............................................................................................................................3 三、设计流程图.........................................................................................................................5 四、程序运行及结果.................................................................................................................6 五、心得体会.............................................................................................................................8 参考文献.....................................................................................................................................9 附录:源程序...........................................................................................................................10 信息论与编码课程设计
哈夫曼编码与译码(附源码).
建立Huffman树进行编码和译码的设计李香兰 2015548947 哈尔滨工业大学计算机科学与技术学院 1501班摘要:建立一个简易的系统,对于给定的一篇英文文章,统计字符出现的概率,并根据概率建立Huffman树,利用Huffman编码对文章进行编码和译码。
掌握Huffman树的建立与应用,并进一步熟练掌握程序的设计流程。
关键词:Huffman树Huffman编码文章译码文件压缩解压缩1.引言:给定一篇文章,统计字符出现的概率,根据概率建立哈夫曼树,并进行哈夫曼编码,进而可以利用哈夫曼编码对文章进行编码与译码和文件压缩、解压缩等操作。
2.程序设计流程(1)文字表述开始进入功能选择界面,包含五种操作:1.读取文章并对字符编码,2.哈夫曼编码信息,3.文章编码,4.文章译码,5.文件压缩,6.文件解压缩,7.退出程序。
操作1:给定一篇文章,统计字符出现的概率,并根据概率建立Huffman树,并利用Huffman树对字符进行Huffman编码。
操作2:显示Huffman编码信息,包括字符,字符出现的概率,Huffman编码。
操作3:对文章进行译码,显示译码信息,并保存。
操作4:对文章进行译码,显示并保存。
操作5:对文件进行压缩,每7位二进制序列对应一个ASCII码。
操作6:对文件进行解压缩。
(2)流程图程序开始程序主界面读取文章并对字符编码哈夫曼编码信息文章编码文章译码退出程序显示文章编码保存文章编码返回上一界面显示文章编码的译码保存文章编码的译码程序结束文件压缩文件解压缩(3)程序数据要求及功能实现主界面1.读取文件并对字符进行编码2.哈夫曼编码信息3.文件编码(1)显示文件编码(2)保存文件编码4.文件译码(1)显示文章编码的译码(2)保存文章编码的译码5.文件压缩6.文件解压缩附:程序源代码/** File: HUFFMANFUNCTION.h* Author: Administrator** Created on 2011年12月19日, 下午6:19 */#ifndef HUFFMANFUNCTION_H#define HUFFMANFUNCTION_H#include <cstdlib>#include<iostream>#include<fstream>#include<math.h>#define max1 150#define max2 50#define max3 256using namespace std;class Htnote {public:char name; //字符名double weight; //权重int lchild; //左孩子int rchild; //右孩子int parent; //父亲Htnote() {weight = 0;lchild = -1;parent = -1;rchild = -1;}};class Name {public:int num; //字符出现的次数char pname; //字符名double lweight; //权值Name() {num = 0;lweight = 0;}};class GetName {public:char namef[max2];int n; //字符的种类int sum; //字符的总数Name letter[max1]; //存储字符信息的类的数组GetName() {sum = 0;n = 0;}void GetWeight()//得到字符的权值{for (int i = 0; i < n; i++) {letter[i].lweight = (double) letter[i].num / sum; //出现的次数除总数得到权值}}int ReadLetter() {ifstream input;cout << "请输入文件名:" << endl;cin >> namef;input.open(namef); //打开文件if (input.fail()) {cout << "该文件不存在!" << endl;return 0;}char ch;ch = input.get();letter[0].pname = ch;letter[0].num++;sum++;while (!input.eof()) {//读取文件中的所有字符int tag = 0;ch = input.get();for (int i = 0; i < n + 1; i++) {if (letter[i].pname == ch) {letter[i].num++;sum++;tag = 1;}}if (tag == 0) {n++;letter[n].pname = ch;letter[n].num++;sum++;}}sum--;input.close();GetWeight(); //得到字符权值}};class CodeNode//编码类{public:char ch; //存储字符char bits[max1]; //存储编码};class Function {public:GetName L;int fn; //定义哈夫曼数组大小Htnote HuffmanT[max3]; //哈夫曼数组CodeNode Code[max1]; //字符编码数组Function() {fn = 0;}void CharHuffmanTCoding()//编码功能实现{int i, f, c;char cd[L.n + 1]; //暂时存储编码的数组int start; //编码读取起始位置cd[L.n] = '\0';for (i = 0; i < L.n; i++) {Code[i].ch = HuffmanT[i].name; //字符信息start = L.n; //起始位置c = i;while ((f = HuffmanT[c].parent) >= 0) {if (HuffmanT[f].lchild == c)//如果为左孩子,为‘0’{cd[--start] = '0';} else//如果为右孩子,为‘1’{cd[--start] = '1';}c = f;}strcpy(Code[i].bits, &cd[start]); //将结果存入对应的编码数组中}}void OutputHuffmanTCode() {cout << "哈夫曼编码:" << endl;cout << "——————————————————————" << endl;cout << "字符\t权值\t\t哈夫曼编码" << endl;for (int i = 0; i < L.n; i++)//输出字符,权值,哈夫曼编码{cout << "——————————————————————" << endl;cout << HuffmanT[i].name << "\t" << HuffmanT[i].weight << "\t";cout << Code[i].bits;cout << endl;}cout << "——————————————————————" << endl;}void InitHT()//哈夫曼初始化{L.ReadLetter();fn = (L.n)*2 - 1;for (int i = 0; i < fn; i++) {if (i < L.n) {HuffmanT[i].name = L.letter[i].pname;HuffmanT[i].weight = L.letter[i].lweight;}}}void SelectMin(int m, int &p1, int &p2)//选择最小的两个节点{int i, j;double m1, m2;m1 = m2 = 1;p1 = p2 = -1;for (i = 0; i < m; i++) {if (HuffmanT[i].parent == -1 && HuffmanT[i].weight < m1)//找出为访问过的最小权值节点{m2 = m1;p2 = p1;m1 = HuffmanT[i].weight;p1 = i;} else if (HuffmanT[i].parent == -1 && HuffmanT[i].weight < m2)//找出为访问的权值第二小结点{m2 = HuffmanT[i].weight;p2 = i;}}}void CreatHT()//建立哈夫曼树{int i, p1, p2;InitHT();for (i = L.n; i < fn; i++) {SelectMin(i, p1, p2);HuffmanT[p1].parent = HuffmanT[p2].parent = i;HuffmanT[i].lchild = p1;HuffmanT[i].rchild = p2;HuffmanT[i].weight = HuffmanT[p1].weight + HuffmanT[p2].weight;}}int OutArticleCode()//显示文章编码{//文章编码操作ifstream input;input.open(f);if (input.fail()) {cout << "文件不存在!" << endl;return 0;}char ch;cout << "文章编码如下:" << endl;while (!input.eof()) {ch = input.get();for (int i = 0; i < L.n; i++) {if (Code[i].ch == ch)cout << Code[i].bits;}}cout << endl;input.close();}int SaveArticleCode()//保存文章编码{ofstream output;ifstream input;char namef1[max2];input.open(f);if (input.fail()) {cout << "该文件不存在!" << endl;return 0;}cout << "请输入保存文章编码的文件名:" << endl;cin >> namef1;output.open(namef1);char ch;while (!input.eof()) {ch = input.get();for (int i = 0; i < L.n; i++) {if (Code[i].ch == ch) {for (int j = 0; j < strlen(Code[i].bits); j++) {output.put(Code[i].bits[j]);}}}}input.close();output.close();cout << "保存完毕!" << endl;}int OutTransCode() {//文章译码操作ifstream input;char namef[max2];cout << "请输入保存文章编码的文件名:" << endl;cin >> namef;input.open(namef);if (input.fail()) {cout << "该文件不存在!" << endl;return 0;}char ch;ch = input.get();int c = 2 * L.n - 2;while (!input.eof()) {if (ch == '0')//遇0搜索左子树{if (HuffmanT[c].lchild >= 0) {c = HuffmanT[c].lchild;}if (HuffmanT[c].lchild == -1)//判断是否到叶子{cout << HuffmanT[c].name; //输出字符c = 2 * L.n - 2; //返回根节点}}if (ch == '1')//遇1搜索右子树{if (HuffmanT[c].rchild >= 0) {c = HuffmanT[c].rchild;}if (HuffmanT[c].rchild == -1)//判断是否到叶子{cout << HuffmanT[c].name; //输出字符c = 2 * L.n - 2; //返回根节点}}ch = input.get();}cout << endl;input.close();}int SaveTransCode() {//保存文章译码ofstream output;ifstream input;char namef[max2];char namef1[max2];cout << "请输入文章编码所在的文件名:" << endl;cin >> namef;input.open(namef);if (input.fail()) {cout << "该文件不存在!" << endl;return 0;}cout << "请输入保存文章译码的文件名:" << endl;cin >> namef1;output.open(namef1);char ch;ch = input.get();int c = 2 * L.n - 2;while (!input.eof()) {if (ch == '0') {if (HuffmanT[c].lchild >= 0) {c = HuffmanT[c].lchild;}if (HuffmanT[c].lchild == -1) {output.put(HuffmanT[c].name);c = 2 * L.n - 2;}}if (ch == '1') {if (HuffmanT[c].rchild >= 0) {c = HuffmanT[c].rchild;}if (HuffmanT[c].rchild == -1) {output.put(HuffmanT[c].name);c = 2 * L.n - 2;}}ch = input.get();}input.close();output.close();cout << "保存完毕!" << endl;}int FileCompression() {//文件压缩功能CreatHT();CharHuffmanTCoding();//保存编码ofstream output;ifstream input;char namef1[] = {"temp.txt"};input.open(f);if (input.fail()) {cout << "该文件不存在!" << endl;return 0;}output.open(namef1);char ch;while (!input.eof()) {ch = input.get();for (int i = 0; i < L.n; i++) {if (Code[i].ch == ch) {for (int j = 0; j < strlen(Code[i].bits); j++) {output.put(Code[i].bits[j]);}}}}input.close();output.close();//压缩文件ofstream File1;ifstream File2;char namef2[max2];cout << "请输入压缩后的文件名:" << endl;cin >> namef2;File1.open(namef2);File2.open(namef1);if (File2.fail()) {cout << "该文件不存在!" << endl;return 0;}char sh;char th;int i = 0;char j = '0';int count = 0;while (!File2.eof()) {sh = File2.get();if (i < 7 && sh != EOF) {count = count + (sh - '0') * pow(2, i);if (sh == '0') {j++;} else {j = '0';}i++;}if (i == 7) {th = count;File1.put(th);i = 0;count = 0;}if (sh == EOF) {th = count;File1.put(th);File1.put(j);i = 0;count = 0;}}File1.close();File2.close();remove(namef1);cout << "文件压缩完毕!" << endl;}int FileDecompression() {//文件解压缩//保存编码fstream output;fstream input;char namef2[max2];char namef1[] = {"temp.txt"};cout << "请输入待解压缩的文件名:" << endl;cin >> namef2;input.open(namef2, ios::in | ios::binary);output.open(namef1, ios::out | ios::binary);if (input.fail()) {cout << "该文件不存在!" << endl;return 0;}char ch;input.read(reinterpret_cast<char*> (&ch), sizeof (ch));char sh;char th = ch;input.read(reinterpret_cast<char*> (&ch), sizeof (ch));int count;char num;char t = '0';char p = '1';while (!input.eof()) {sh = th;th = ch;input.read(reinterpret_cast<char*> (&ch), sizeof (ch));count = sh;if (ch != EOF) {for (int i = 0; i < 7; i++) {num = count % 2 + '0';output.write(reinterpret_cast<char*> (&num), sizeof (num));count = count / 2;}}if (ch == EOF) {for (int i = 0; i < 7; i++) {num = count % 2 + '0';output.write(reinterpret_cast<char*> (&num), sizeof (num));count = count / 2;if (count == 0) {break;}}for (int i = 0; i < th - '0'; i++) {output.write(reinterpret_cast<char*> (&t), sizeof (t));}}}output.close();input.close();//解压文件fstream File1;fstream File2;char namef3[max2];cout << "请输入解压后的文件名:" << endl;cin >> namef3;File2.open(namef1, ios::in | ios::binary);File1.open(namef3);if (File2.fail()) {cout << "该文件不存在!" << endl;return 0;}cout << "解压后的文件内容为:" << endl;File2.read(reinterpret_cast<char*> (&ch), sizeof (ch));int c = 2 * L.n - 2;while (!File2.eof()) {if (ch == '0') {if (HuffmanT[c].lchild >= 0) {c = HuffmanT[c].lchild;}if (HuffmanT[c].lchild == -1) {cout << HuffmanT[c].name;File1.write(reinterpret_cast<char*> (&HuffmanT[c].name), sizeof (HuffmanT[c].name));c = 2 * L.n - 2;}}if (ch == '1') {if (HuffmanT[c].rchild >= 0) {c = HuffmanT[c].rchild;}if (HuffmanT[c].rchild == -1) {cout << HuffmanT[c].name;File1.write(reinterpret_cast<char*> (&HuffmanT[c].name), sizeof (HuffmanT[c].name));c = 2 * L.n - 2;}}File2.read(reinterpret_cast<char*> (&ch), sizeof (ch));}cout << endl;File2.close();File1.close();remove(namef1);cout << "解压完毕!" << endl;}};#endif /* HUFFMANFUNCTION_H */====================================================================== /** File: main.cpp* Author: Administrator** Created on 2011年12月13日, 上午9:09*/#include <iostream>#include "HUFFMANFUNCTION.h"using namespace std;/***/int main(int argc, char** argv){Function *a = new Function;while (1){//主界面显示cout << endl << endl << endl;cout << "<<==================功能选择===============>>" << endl;cout << " 【1】读取文章并对字符编码" << endl;cout << " 【2】哈夫曼编码信息" << endl;cout << " 【3】文章编码" << endl;cout << " 【4】文章译码" << endl;cout << " 【5】压缩文件" << endl;cout << " 【6】解压缩文件" << endl;cout << " 【7】退出程序" << endl;cout << "=========================================================" << endl << endl;char ch;cout << "====>>请选择功能:";cin >> ch;switch (ch){case '1'://读取文章并对字符编码{delete a;a = new Function;system("cls");a->CreatHT();a->CharHuffmanTCoding();cout << "操作完毕!" << endl;system("pause");system("cls");break;}case '2'://哈夫曼编码信息{system("cls");a->OutputHuffmanTCode();system("pause");system("cls");break;}case '3'://文章编码{system("cls");while (1){cout << endl;cout << "========>>1.显示文章编码" << endl;cout << "========>>2.保存文章编码" << endl;cout << "========>>3.返回上一界面" << endl;char ch1;cout << endl << "===>>请选择功能:";cin >> ch1;switch (ch1){case '1'://显示文章编码{system("cls");a->OutArticleCode();system("pause");system("cls");continue;}case '2'://保存文章编码{system("cls");a->SaveArticleCode();system("pause");system("cls");continue;}case '3'://返回上一界面{break;}default:{system("cls");cout << "输入错误,请重新输入!" << endl;continue;}}system("cls");break;}break;}case '4'://文章译码system("cls");while (1){cout << endl;cout << "========>>1.显示文章编码的译码" << endl;cout << "========>>2.保存文章编码的译码" << endl;cout << "========>>3.返回上一界面" << endl;char ch1;cout << endl << "===>>请选择功能:";cin >> ch1;switch (ch1){case '1'://显示文章编码的译码{system("cls");a->OutTransCode();system("pause");system("cls");continue;}case '2'://保存文章编码的译码{system("cls");a->SaveTransCode();system("pause");system("cls");continue;}case '3'://返回上一界面{break;}default:{system("cls");cout << "输入错误,请重新输入!" << endl;continue;}}system("cls");break;}break;case '5':{delete a;a = new Function;system("cls");a->FileCompression();system("pause");system("cls");continue;}case '6':{system("cls");a->FileDecompression();system("pause");system("cls");continue;}case '7':{return 0;}default:{system("cls");cout << "功能选择错误,请重新输入!" << endl;break;}}}return 0;}。
哈夫曼编码
哈夫曼编码
1952年哈夫曼提出了一种构造最佳码的方法 称之为哈夫曼编码。 哈夫曼编码适用于多元独立信源
对于独立信源来说,哈夫曼编码是最佳码 他充分的利用了信源的概率特性进行编码,
编码方法
(1)将信源消息符号按其出现的概率大小依次 排列 (2)取两个概率最小的字母分别配以0和1两个 码元,并将这两个概率相加作为一个新字 母的概率,与未分配的二进符号的字母重 新排队
1 哈夫曼码的编码方法保证了概率大的符号对应于 短码,概率小的符号对应于长码,充分利用了短 码。 2 缩减信源的最后二个码字总是最后一位不同,从 而保证了哈夫曼码是即时码。 3 每次缩减信源的最长两个码字有相同的码长。 三个特点保证了哈夫曼码是最佳码
多进制哈夫曼编码
对于多进制哈夫曼码,为了提高编码效率, 就要使长码的符号数量尽量少、概率尽量 小,所以信源符号数量尽量满足
编码方法
(3)对重排后的两个概率最小符号重复步骤(2) 的过程。
(4)不断继续上述过程,直到最后两个符号配 以0和1为止。 (5)从最后一级开始,向前返回得到各个信源 符号所对应的码元序列,即相应的码字。
例5-7
信源 符号 概率 0.20 编码过程 码字 码 长 0.39 0.35 0 0.26 1 10 0.61 0 1.0 11 0.39 1 000 001 2
编码效率也相等
H(X ) 0.965 K
码方差 码字长度偏离平均长度的程度
l2 E k i K
p(a )(k
2 q i 1 i
i
K )2
第一种哈夫曼码的码方差
1.36
2 l1
第二种哈夫曼码的码方差
0.16
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
毕业设计(论文) 常用软件课程设计 河北工业大学 《数据结构》课程实验
实 验 报 告
题目:基于哈夫曼编码的通信系统的设计与实现 专业:计算机科学与技术 班级:计1301班 姓名:张路浩 刘禄源 刘磊波 李浩川 邹博睿 王超 完成日期: 2015-1-13 毕业设计(论文)
常用软件课程设计 一、试验内容 1)初始化处理:建立通信系统 (1)建立有100句中文的信息集合,每个句子称为一条信息。 (2)输入编码参数: ① 从终端输入编码字符集大小n,字符编码长度m(设n为4,m为8); ② 从终端输入编码字符(设为A,B,C,D); (3)生成每条信息的字符编码,构造字符编码集合; (4)计算每个字符在字符编码集合中出现的概率; (5)根据字符概率构造哈夫曼树,求出每个字符的二进制编码。 2)发送端信息编码 (1)用户从信息集合中选择一条信息,找到该信息对应的字符编码; (2)根据该信息的字符编码,哈夫曼树求出的每个字符的二进制编码,构造出该信息的二进制编码,记录该二进制编码。(由于是软件模拟,没有发送设备,发送端的编码工作完成)。 3)接受端信息译码 (1)根据得到的信息的二进制编码,利用哈夫曼树求出的每个字符的二进制编码,还原出信息的字符编码; (2)根据信息的字符编码,找到对应的信息。 5、实现提示 (1)本试验涉及到通讯学科的编码理论和信息学科的数据压缩技术。 (2)根据参数生成的通信系统的所有信息的有效存储问题。 (3)信息字符编码可参考随机数的方式生成,且要求保持唯一性
二、试验目的 (1)掌握二叉树的存储结构及其相关操作。 (2)掌握构造哈夫曼树的基本思想,及其编码/译码过程。 三、流程图 毕业设计(论文) 常用软件课程设计 用字符集对信息进行字符编码void CreatCode(HCodeType& HT,int n)
根据各字符构的频度构造哈夫曼树 CreatHFMTree(HT,n) 哈夫曼编码 CreatHFMCode(HT,HFMCode,n); 输出文字信息和对应的哈夫曼编码 开始 结束 定义字符集大小n 输入n 输入编码长度p 输入字符集内容 HT.HFMTree[i].word 定义汉字信息 string message[10] 设置随机数种子 srand(time(NULL)); 通过随机数函数对汉字信息用字符集进行编码psw[i] 统计汉字信息字符编码中各字符出现的频度HT.HFMTree[k].weight 指针初始化 HT.HFMTree[i].parent = -1; HT.HFMTree[i].rchild = -1; HT.HFMTree[i].lchild = -1; 逐个非叶结点构造
寻找具有最小、次小值的根建树
Y 父指针为空
比原来最小的还要小 原来的最小变为次小,
记下新的最小值 Y
N 比原来的次
小还小 记下新的次小值
链接父节点和兄弟结点,i++
i<2n-1 N Y
将各信息的字符编码进行哈弗曼树编码 毕业设计(论文)
常用软件课程设计 四、源程序代码 #include #include #include #include using namespace std; const int n=4;//叶子节点个数 const int MAXVALUE = 9999; int m,p; //编码参数 string l; int size; //构造哈夫曼树结点 typedef struct{ int weight;//权值 int parent;//父节点 int lchild;//左子树 int rchild;//右子树 char word;//编码字符 }HNodeType;
//构造哈夫曼编码数组 typedef struct{ HNodeType HFMTree[2*n-1];//结点数 int bit[n]; int start; }HCodeType;
HCodeType HT; HCodeType HFMCode[n]; string message[10]={ {"人之初"},{"性本善"},{"性相近"}, {"习相远"},{"苟不教"},{"性乃迁"},{"教之道"},{"贵以专"}, {"昔孟母"},{"择邻处"}}; string psw[10];//存储编码
//对信息进行编码 void CreatCode(HCodeType& HT,int n) {
int i,j,k; char ch;//存储编码的字符集 //权重初始化 for(i=0;i<2*n-1;i++){ 毕业设计(论文) 常用软件课程设计 HT.HFMTree[i].weight=0; } cout<<"请输入编码字符集的大小:m = "; cin>>m; cout<<"请输入编码长度大小:p = "; cin>>p; cout<<"请输入编码字符:" //创建哈弗曼树 void CreatHFMTree(HCodeType& HT,int n) { int i,j; int m1,x1,m2,x2; for(i = 0;i<2*n-1;i++){ HT.HFMTree[i].parent = -1; HT.HFMTree[i].rchild = -1; 毕业设计(论文) 常用软件课程设计 HT.HFMTree[i].lchild = -1; } for(i = 0;i{ x1 = x2 =MAXVALUE; m1 = m2 =0; for(j = 0;jif(HT.HFMTree[j].parent==-1&&HT.HFMTree[j].weightx2 = x1; m2 = m1; x1 = HT.HFMTree[j].weight; m1 = j; } else if(HT.HFMTree[j].parent==-1&&HT.HFMTree[j].weightx2 = HT.HFMTree[j].weight; m2 = j; } } HT.HFMTree[m1].parent=n+i; HT.HFMTree[m2].parent=n+i; HT.HFMTree[n+i].weight=HT.HFMTree[m1].weight+HT.HFMTree[m2].weight; HT.HFMTree[n+i].lchild=m1; HT.HFMTree[n+i].rchild=m2; } cout<<"**************************************************************" //对字符集编码 void CreatHFMCode(HCodeType& HT,HCodeType HFMCode[],int n){ HCodeType cd; int i,j,c,p; for(i = 0;icd.start = n-1; c = i; p = HT.HFMTree[i].parent; while(p != -1){