编码理论实验报告实验一霍夫曼编码中信息熵及编码效率的实验
huffman编码实验

一、实验目的 1、学习 Matlab 软件的使用和编程; 2、进一步深入理解 Huffman 编码算法的原理; 3、提高独立进行算法编程的能力。 二、实验内容 1、用 Matlab 实现 Huffman 编码算法程序; 2、要求程序输出显示所有的码字以及编码效率; 3、设计简单的输入界面(可以是简单的文字提示信息) ,程序运 行时提示用户输入代表信源符号概率的向量; 要对用户输入的概 率向量进行合法性检查。 三、实验原理 1、二进制 Huffman 编码的基本原理及算法 (1) 把信源符号集中的所有符号按概率从大到小排队。 (2) 取概率最小的两个符号作为两片叶子合并(缩减)到一个 节点。 (3) 视此节点为新符号, 其概率等于被合并 (缩减) 的两个概率之和, 参与概率排队。 (4) 重复(2)(3)两步骤,直至全部符号都被合并(缩减)到根。 (5) 从根出发,对各分枝标记 0 和 1。从根到叶的路径就给出了各个 码字的编码和码长。 2、程序设计的原理 (1)程序的输入: 以一维数组的形式输入要进行 huffman 编码的信源
% 矩阵 c 的第 n-i 的
第一个元素的 n-1 的字符赋值为对应于 a 矩阵中
第 n-i+1 行中值为 1 的位置在 c 矩阵中的编码值
c(n-i,n)='0' %根据之前的规则,在分支的第一个元素最后补 0 c(n-i,n+1:2*n-1)=c(n-i,1:n-1) %矩阵 c 的第 n-i 的第二个元素的 n-1 的字符与第 n-i 行的第一个元素
符号的概率,在运行该程序前,显示文字提示信息,提示所要输入的 概率矢量;然后对输入的概率矢量进行合法性判断,原则为:如果概 率矢量中存在小于 0 的项,则输入不合法,提示重新输入;如果概率 矢量的求和大于 1,则输入也不合法,提示重新输入。 (2)huffman 编码具体实现原理: 1>在输入的概率矩阵 p 正确的前提条件下,对 p 进行排序, 并用 矩阵 L 记录 p 排序之前各元素的顺序, 然后将排序后的概率数组 p 的 前两项,即概率最小的两个数加和,得到新的一组概率序列,重复以 上过程, 最后得到一个记录概率加和过程的矩阵 p 以及每次排序之前 概率顺序的矩阵 a。 2>新生成一个 n-1 行 n 列, 并且每个元素含有 n 个字符的空白矩 阵,然后进行 huffman 编码: � 将 c 矩阵的第 n-1 行的第一和第二个元素分别令为 0 和 1(表示 在编码时,根节点之下的概率较小的元素后补 0,概率较大的元 素后补 1,后面的编码都遵守这个原则) � 然后对 n-i-1 的第一、 二个元素进行编码, 首先在矩阵 a 中第 n-i 行找到值为 1 所在的位置,然后在 c 矩阵中第 n-i 行中找到对应 位置的编码(该编码即为第 n-i-1 行第一、二个元素的根节点) , 则矩阵 c 的第 n-i 行的第一、二个元素的 n-1 的字符为以上求得 的编码值,根据之前的规则,第一个元素最后补 0,第二个元素 最后补 1,则完成该行的第一二个元素的编码, � 最后将该行的其他元素按照“矩阵 c 中第 n-i 行第 j+1 列的值等
优秀Huffman编码 实验报告

实验二:Huffman 编码的实现实验学时:3实验类型:(演示、验证、综合、√设计、研究)实验要求:(√必修、选修)一、 实验目的 理解和掌握huffman 编码的基本原理和方法,实现对信源符号的huffman 编码。
二、 实验内容1. 理解和掌握huffman 编码的基本原理和方法2. 通过MATLAB 编程实现对单信源符号的huffma 编码3. 计算信源的信息熵、平均码长以及编码效率三、 实验原理1.Huffman 编码按信源符号出现的概率而编码,其平均码长最短,所以是最优码。
2.无失真信源编码定理:对于熵为H (X )的离散无记忆的平稳信源,必存在一种无失真编码,使每符号的平均码长满足不等式:()()1log log H S H S L r r≤<+ 3.二元Huffman 编码:若将编码设计为长度不等的二进制编码,即让待传字符串中出现概率大的字符采用尽可能短的码字,而把长的码字分配给概率小的信源符号。
构造方法如下:(a ) 将信源概率分布按大小以递减次序排列;合并两概率最小者,得到新信源;并分配0/1符号。
(b ) 新信源若包含两个以上符号返回(a ),否则到(c )。
(c ) 从最后一级向前按顺序写出每信源符号所对应的码字。
四、 实验数据源1.12345[]:0.40.20.20.10.1s s s s s X P ⎧⋅⎨⎩:{0,1}X2.123456[]:0.240.200.180.160.140.08s s s s s s X P ⎧⋅⎨⎩:{0,1}X 五、实验组织运行要求以学生自主训练为主的开放模式组织教学六、实验条件(1)微机(2)MATLAB 编程工具七、实验原理七、实验代码clear% S=[0.4,0.2,0.2,0.1,0.1]; S=[0.24,0.20,0.18,0.16,0.14,0.08];% S=[0.20,0.19,0.18,0.17,0.15,0.10,0.01];S0=sort(S); %将序列进行升序排列S1=fliplr(S0); %将升序排列的概率进行左右翻转得到降序排列t=length(S1); %得到信源符号的个数coding_table=[S1']; %创建编码过程表,第一列for i=1:length(S1)-1s=coding_table(t,i)+coding_table(t-1,i); %最小两个值相加S1(t-1)=s;S1(t)=0;t=t-1;S1=fliplr(sort(S1)); %进行重新降序排列coding_table=[coding_table,S1']; %排序结果加入到编码过程表for j=1:length(S1)if s==S1(j)b(i)=j; %记录两个最小概率相加得到的值在新排序中的位置。
编码理论实验报告

一、实验目的1. 理解编码理论的基本概念和原理;2. 掌握哈夫曼编码和香农编码的方法;3. 熟悉编码效率的计算方法;4. 培养编程能力和实践操作能力。
二、实验原理1. 编码理论:编码理论是研究信息传输、存储和处理中信息压缩和编码的理论。
其目的是在保证信息传输质量的前提下,尽可能地减少传输或存储所需的数据量。
2. 哈夫曼编码:哈夫曼编码是一种根据字符出现频率进行编码的方法,字符出现频率高的用短码表示,频率低的用长码表示,从而达到压缩数据的目的。
3. 香农编码:香农编码是一种基于信息熵的编码方法,根据字符的概率分布进行编码,概率高的字符用短码表示,概率低的字符用长码表示。
4. 编码效率:编码效率是指编码后数据长度与原始数据长度的比值。
编码效率越高,表示压缩效果越好。
三、实验内容1. 使用MATLAB软件实现哈夫曼编码和香农编码;2. 对给定信源进行编码,并计算编码效率;3. 对比哈夫曼编码和香农编码的效率。
四、实验步骤1. 编写哈夫曼编码程序:首先,统计信源中各个字符的出现频率;然后,根据频率构造哈夫曼树;最后,根据哈夫曼树生成编码。
2. 编写香农编码程序:首先,计算信源熵;然后,根据熵值生成编码。
3. 编码实验:对给定的信源进行哈夫曼编码和香农编码,并计算编码效率。
4. 对比分析:对比哈夫曼编码和香农编码的效率,分析其优缺点。
五、实验结果与分析1. 哈夫曼编码实验结果:信源:'hello world'字符频率:'h' - 2, 'e' - 1, 'l' - 3, 'o' - 2, ' ' - 1, 'w' - 1, 'r' - 1, 'd' - 1哈夫曼编码结果:'h' - 0'e' - 10'l' - 110'o' - 1110' ' - 01'w' - 101'r' - 100'd' - 1001编码效率:1.52. 香农编码实验结果:信源:'hello world'字符频率:'h' - 2, 'e' - 1, 'l' - 3, 'o' - 2, ' ' - 1, 'w' - 1, 'r' - 1, 'd' - 1香农编码结果:'h' - 0'e' - 10'l' - 110'o' - 1110' ' - 01'w' - 101'r' - 100'd' - 1001编码效率:1.53. 对比分析:哈夫曼编码和香农编码的效率相同,均为1.5。
霍夫曼编码设计实验报告

一、实验目的1. 理解霍夫曼编码的基本原理和算法流程。
2. 掌握霍夫曼编码的构建过程和编码方法。
3. 通过实验验证霍夫曼编码在数据压缩方面的效果。
4. 提高编程能力和数据结构应用能力。
二、实验环境1. 操作系统:Windows 102. 编程语言:C++3. 开发工具:Visual Studio 2019三、实验原理霍夫曼编码是一种基于字符出现频率进行编码的数据压缩方法。
其基本原理如下:1. 对字符进行统计,得到每个字符出现的频率。
2. 根据频率对字符进行排序,频率高的字符排在前面。
3. 构建霍夫曼树,将频率高的字符放在树的左侧,频率低的字符放在树的右侧。
4. 从树根到叶子节点,为每个字符分配一个二进制编码,频率高的字符用较短的编码表示,频率低的字符用较长的编码表示。
四、实验步骤1. 定义一个结构体HuffmanNode,用于存储字符及其频率。
2. 实现一个函数用于统计字符频率。
3. 实现一个函数用于构建霍夫曼树。
4. 实现一个函数用于生成霍夫曼编码。
5. 实现一个函数用于解码霍夫曼编码。
6. 编写主函数,进行实验验证。
五、实验过程1. 定义结构体HuffmanNode,用于存储字符及其频率。
```cppstruct HuffmanNode {char ch;int weight;HuffmanNode lchild, rchild;};```2. 实现一个函数用于统计字符频率。
```cppvoid StatFrequency(char str, int freq) {int length = strlen(str);for (int i = 0; i < 256; ++i) {freq[i] = 0;}for (int i = 0; i < length; ++i) {freq[(int)str[i]]++;}}```3. 实现一个函数用于构建霍夫曼树。
```cppHuffmanNode CreateHuffmanTree(int freq, int length) {HuffmanNode nodes = new HuffmanNode[length + 1];for (int i = 0; i < length; ++i) {nodes[i].ch = 'a' + i;nodes[i].weight = freq[i];nodes[i].lchild = nullptr;nodes[i].rchild = nullptr;}for (int i = length; i < length + 1; ++i) {nodes[i].ch = '\0';nodes[i].weight = 0;nodes[i].lchild = nullptr;nodes[i].rchild = nullptr;}for (int i = 0; i < length - 1; ++i) {HuffmanNode minNode1 = &nodes[0];HuffmanNode minNode2 = &nodes[1];for (int j = 0; j < length + 1; ++j) {if (nodes[j].weight < minNode1->weight) {minNode2 = minNode1;minNode1 = &nodes[j];} else if (nodes[j].weight < minNode2->weight && nodes[j].weight > minNode1->weight) {minNode2 = &nodes[j];}}nodes[i].weight = minNode1->weight + minNode2->weight;nodes[i].lchild = minNode1;nodes[i].rchild = minNode2;minNode1->parent = &nodes[i];minNode2->parent = &nodes[i];}return &nodes[length - 1];}```4. 实现一个函数用于生成霍夫曼编码。
信息论课程实验报告—哈夫曼编码

*p2 = j;
}
}
void CreateHuffmanTree(HuffmanTree T)
{
int i,p1,p2;
InitHuffmanTree(T);
InputWeight(T);
for(i = n;i < m;i++)
4)依次继续下去,直至信源最后只剩下两个信源符号为止,将这最后两个信源符号分别用二元码符号“0”和“1”表示;
5)然后从最后—级缩减信源开始,进行回溯,就得到各信源符号所对应的码符号序列,即相应的码字。
四、实验目的:
(1)进一步熟悉Huffman编码过程;(2)掌握C语言递归程序的设计和调试技术。以巩固课堂所学编码理论的知识。
#include "stdio.h"
#include "stdlib.h"
#include <float.h>
#include <math.h>
#define n 8
#define m 2*n-1
typedef struct
{
float weight;
int lchild,rchild,parent;
}
}
void InputWeight(HuffmanTree T)
{
float temp[n] = {0.20,0.18,0.17,0.15,0.15,0.05,0.05,0.05};
for(int i = 0;i < n;i++)
T[i].weight = temp[i];
}
Huffman编解码实验报告

Huffman编解码实验报告⽂本⽂件的⼆进制预统计Huffman编解码⼀、实验⽬的(1) 熟悉Huffman编解码算法;(2) 理解Huffman编码的最佳性。
⼆、实验内容1、编程思想霍夫曼(Huffman)编码是1952年为⽂本⽂件⽽建⽴,是⼀种统计编码。
属于⽆损压缩编码。
霍夫曼编码的码长是变化的,对于出现频率⾼的信息,编码的长度较短;⽽对于出现频率低的信息,编码长度较长。
这样,处理全部信息的总码长⼀定⼩于实际信息的符号长度。
计算机编程实现时,⾸先统计带编码的⽂本⽂件中各个字符出现的概率,然后将概率作为节点的权值构建huffman树。
编码时从叶⼦节点出发,如果这个节点在左⼦树上,则编码0,否则编码1,直到根节点为⽌,所得到的01序列即为该叶⼦节点的编码。
所有叶⼦节点的编码构成⼀个码本。
有两种译码⽅法:(1)按位读⼊码字,从已建好的Huffman树的根节点开始,若码字为“0”,则跳到左⼦树,若为“1”则跳到右⼦树,直到叶⼦结点为⽌,输出叶⼦接点所表⽰的符号。
(2)由于Huffman编码是唯⼀码,还有另⼀种译码⽅法,每读⼊⼀位编码就去码本中去匹配相应的码字,若匹配不成功,则继续读⼊下⼀个编码,直到匹配成功为⽌。
显然前⼀种⽅法⽐较简便,本程序采⽤便是该⽅法。
2、程序流程图3、编程实现本实验采⽤⽤C 语⾔程序语⾔,VC++ 6.0编程环境。
(1)数据结构构造存放符号及其权值的存储结构如下 typedef struct {unsigned char symbol; //符号的ASCII 码值 int sweight; //权值}syml_weit;syml_weit *sw;构造huffman 树存储结构如下:typedef struct {int weit; //权值int lchd; //左孩⼦地址 int rchd; //右孩⼦地址 int part; //双亲地址 }hufmtree;hufmtree *htree;(2)函数本程序共包含5个函数:⼀个主函数:void main(), 4个⼦函数:void CountWeight(unsigned char *DataBuf,int FileLen); void BuildTree();void HufmCode(unsigned char *DataBuf,int FileLen); void HufmDCode(unsigned char *CDataBuf,int CDataLen); 其功能分别CountWeight----计算⽂本⽂件中各符号的权值; BuildTree-------构建Huffman 树,形成码本; HufmCode---------对⽂本⽂件进⾏编码; HufmDCode-------进⾏译码。
二元霍夫曼编码 - 信息论与编码实验报告

计算机与信息工程学院综合性实验报告一、实验目的根据霍夫曼编码的原理,用MATLAB设计进行霍夫曼编码的程序,并得出正确的结果。
二、实验仪器或设备1、一台计算机。
2、MATLAB r2013a。
三、二元霍夫曼编码原理1、将信源消息符号按其出现的概率大小依次排列,p1>p2>…>p q2、取两个概率最小的字母分别配以0和1两个码元,并将这两个概率相加作为一个新字母的概率,从而得到只包含q-1个符号的新信源S1。
3、对重排后的缩减信源S1重新以递减次序排序,两个概率最小符号重复步骤(2)的过程。
4、不断继续上述过程,直到最后两个符号配以0和1为止。
5、从最后一级开始,向前返回得到各个信源符号所对应的码元序列,即相应的码字。
四、霍夫曼编码实现程序function [outnum]=lml_huffman(a)%主程序,输入一组概率,输出此组概率的霍夫曼编码%a:一组概率值,如a=[0.2 0.3 0.1 0.4]等%outnum:输出的霍夫曼码,以cell中的字符数组表示if sum(a)~=1warning('输入概率之和不为“1”,但程序仍将继续运行')end[cho,sequ,i,l]=probality(a);global lmlcode %用于输出霍夫曼码,定义为cell型global cellnum %用于编码的累加计算cellnum=1;lmlcode=cell(l,1);j=1; %第一部分add_num=char;[l_add]=addnum(add_num,i,j,l);[output,m]=disgress(sequ,i,j,l,l_add);dealnum(output,m); %在全局变量中输出霍夫曼码j=2; %第二部分[l_add]=addnum(add_num,i,j,l);[output,n]=disgress(sequ,i,j,l,l_add);dealnum(output,n);[outnum]=comset(lmlcode,cho(1,:));%将概率和编码进行关联function [output]=addnum(input,i,j,l)%对概率矩阵中每一行最后两个不为0的数进行编码,即在某个编码后添加0,1或空%输出:% input:输入的某个未完成的编码% (i,j):当前检索目标在sequ矩阵中的位置% l:sequ矩阵的列数%PS: sequ矩阵在此函数中未用到%PS:此函数为编码第一步if j==(l-i)output=[input '0'];else if j==(l-i+1)output=[input '1'];elseoutput=input;endendfunction [ecode]=comset(code,pro)%将概率和编码进行关联%code:已编成的霍夫曼码%pro:输入的一组概率%ecode:最终完成的码l=length(code);ecode=cell(l,2);for i=1:llang(i)=length(code{i});end[a,b]=sort(lang);for i=1:lecode{i,1}=code{b(i)};ecode{i,2}=pro(i);endfunction [final,a]=dealnum(imput,m)%整理并在全局变量中输出已完成的霍夫曼码%输入: imput:程序运算后的生成cell型矩阵% m:标识数%输出: final:整理后的霍夫曼码% a:标识数global lmlcodeglobal cellnumif m==1lmlcode{cellnum}=imput;cellnum=cellnum+1;final='';a='';else if m==2[final1,a1]=dealnum(imput{1,1},imput{1,2});[final2,a2]=dealnum(imput{2,1},imput{2,2});[final3,a3]=dealnum(final1,a1);[final4,a4]=dealnum(final2,a2);final=[final3 final4];a=[a3 a4];elsefinal=imput;a=m;endendfunction [outnum,p]=findsumother(sequ,i,j,l,add_num)%当前检索目标在sequ(i,j)处为非1时的处理程序,即跳转到下一级进行整理%输入: sequ:概率转移矩阵% (i,j):当前检索目标在sequ矩阵中的位置% l:sequ矩阵的列数% add_num:当前进行的编码%输出:(与disgress类同)% outnum:进行霍夫曼编码,用cell型表示% p:标识数j=l-i+2-sequ(i,j);i=i-1;[add_num1]=addnum(add_num,i,j,l);[outnum,p]=disgress(sequ,i,j,l,add_num1);function [outnum1,outnum2,p,q]=findsumis1(sequ,i,j,l,add_num)%当前检索目标在sequ(i,j)处为1时的处理程序,%即对下一级的最小两概率进行求和移位编码整理%输入: sequ:概率转移% (i,j):当前检索目标在sequ矩阵中的位置% l:sequ矩阵的列数% add_num:当前进行的编码%输出:(与disgress类同)% outnum1&[outnum2:进行霍夫曼编码,用cell型表示% p&q:标识数i=i-1;j1=l-i;j2=l-i+1;[add_num1]=addnum(add_num,i,j1,l);[outnum1,p]=disgress(sequ,i,j1,l,add_num1);[add_num2]=addnum(add_num,i,j2,l);[outnum2,q]=disgress(sequ,i,j2,l,add_num2);function [output,m]=disgress(sequ,i,j,l,add_num)%当前检索目标,累加数,输出下一级霍夫曼码及其个数,此函数被调用次数最多%输入:sequ:概率转移矩阵% (i,j):当前检索目标在sequ矩阵中的位置% l:sequ矩阵的列数% add_num:当前进行的编码%输出:output:进行霍夫曼编码,用cell型表示% m:标识数%PS:此函数为编码第二步if i~=1if sequ(i,j)==1[output1,output2,p,q]=findsumis1(sequ,i,j,l,add_num);output=cell(2);output{1,1}=output1;output{1,2}=p;output{2,1}=output2;output{2,2}=q;m=2;else if sequ(i,j)~=1[output1,p]=findsumother(sequ,i,j,l,add_num);output=output1;m=p;endendelseoutput=add_num;m=1;end五、实验程序实现方法演示若在command window中输入的概率数组为p=[0.1 0.15 0.20 0.25 0.30]使用子函数[output,sequ,i,j]=probality(p)对此组概率进行预处理,处理结果如下图所示:图5.1 概率数据处理过程简图图5.2 对图1中数据的转移方式标示图图2标明了对图1中各数据的位置转移过程。
哈夫曼编码实验报告

赫夫曼编码实验报告一、实验内容实现赫夫曼编码的算法二、哈夫曼编码的实验步骤1.输入n个信源符号及其对应的权值2.利用select()函数找出权值最小的两个信源,并各自分配一个码元“0”“1”,并将这两个信源合并为一个新的信源,其权值为这两个最小信源的权值之和,得到一个包n-1个信源符号的新信源,这一过程叫做信源的第一次缩减3.重复步骤二,直到只剩下两个符号为止,此时从最后一级缩减信源开始,依编码路经向前返回,得到各信源符号所对应的码字4.输出信息熵,平均码长以及编码效率三、源代码#include<iostream>#include <math.h>using namespace std;#define MAX 100typedef struct{int weight;int parent,Lc,Rc;char data;}HTNode,*HTree; //动态分配数组存储赫夫曼树typedef char * *HCode;void HuffmanCode(HTree &HT,HCode &HC,int *w,int n);void Select(HTree &HT,int n,int &s1,int &s2);void inputCode();void outputCode(HCode HC,char *data,int *w,int n);const int n=27;int flag=0;HTree Ht;HCode Hc;int num;void HuffmanCode(HTree &HT,HCode &HC,int *w,int n){//w存放n个字符权值(均>0),构造赫夫曼树HT,并求n个字符赫夫曼编码HC。
int m,i,s1,s2;//s1,s2为在HT[1..i-1]中parent为0且weight最小的两个结点if(n<=1) return;//如果结点小于或等于1个,则调用函数出错,退出函数m=2*n-1;//m为赫夫曼树的总结点数HT=(HTree)malloc((m+1)*sizeof(HTNode));// 对赫夫曼树进行初始化for(i=1;i<=n;i++) {HT[i].data=0;HT[i].weight=w[i-1];HT[i].parent=0;HT[i].Lc=0;HT[i].Rc=0;}for(;i<=m;i++) {HT[i].data=0;HT[i].weight=0;HT[i].parent=0;HT[i].Lc=0;HT[i].Rc=0;}//***************创建HuffmanTree******************char *cd;int start,c,f;for(i=n+1;i<=m;++i){Select(HT,i-1,s1,s2);HT[s1].parent=HT[s2].parent=i;HT[i].Rc=s2;HT[i].weight=HT[s1].weight+HT[s2].weight;}//从叶子到根逆向求每个字符的赫夫曼编码HC=(HCode)malloc((n+1)*sizeof(char*)); //分配n个字符编码的头指针向量cd=(char*)malloc(n*sizeof(char)); //分配求编码的工作空间cd[n-1]='\0'; // 编码结束符for(i=1;i<=n;i++){ // 逐个字符求赫夫曼编码start=n-1; // 编码结束符位置for(c=i,f=HT[i].parent;f!=0;c=f,f=HT[f].parent)// 从叶子到根逆向求编码if(HT[f].Lc==c)cd[--start]='0';elsecd[--start]='1';HC[i]=(char*)malloc((n-start)*sizeof(char));// 为第i个字符编码分配空间strcpy(HC[i],&cd[start]); //从cd复制编码(串)到HC }free(cd);}//HuffmanCode//s1为权值最小的根结点void Select(HTree &HT,int n,int &s1,int &s2){//在HT[1..n]选择parent为0且weight最小的两个结点,其序号分别为s1,s2。
霍夫曼树编码实验报告(3篇)

第1篇一、实验背景霍夫曼树编码是一种基于字符频率进行数据压缩的算法,由David A. Huffman在1952年提出。
该算法通过构建霍夫曼树,为不同频率的字符分配不同长度的编码,从而实现数据压缩。
本实验旨在通过C语言实现霍夫曼树编码,并验证其压缩和解压缩效果。
二、实验目的1. 理解霍夫曼树编码的基本原理和步骤。
2. 掌握C语言实现霍夫曼树编码的方法。
3. 评估霍夫曼树编码的压缩效果和解压缩准确性。
三、实验原理霍夫曼树编码的核心思想是构建一棵霍夫曼树,该树由字符和它们的频率构成。
霍夫曼树的构建过程如下:1. 统计输入数据中每个字符的频率。
2. 将字符和频率作为节点,构建最小堆(优先队列)。
3. 重复以下步骤,直到堆中只剩下一个节点:a. 从堆中取出两个频率最小的节点,作为左右子节点。
b. 将这两个节点合并为一个新节点,其频率为两个节点频率之和。
c. 将新节点插入堆中。
4. 最小堆中的最后一个节点即为霍夫曼树的根节点。
霍夫曼树的叶子节点代表字符,非叶子节点代表子节点的频率之和。
根据霍夫曼树的构建,可以生成每个字符的编码,频率高的字符分配较短的编码,频率低的字符分配较长的编码。
四、实验步骤1. 数据准备:选择一段文本数据作为实验对象。
2. 字符频率统计:统计文本数据中每个字符的出现次数。
3. 构建霍夫曼树:根据字符频率构建霍夫曼树。
4. 生成编码表:根据霍夫曼树生成字符编码表。
5. 编码数据:使用编码表对文本数据进行编码。
6. 解压缩数据:根据编码表对编码后的数据进行解压缩。
7. 结果分析:比较原始数据和压缩数据的差异,评估压缩效果和解压缩准确性。
五、实验结果1. 字符频率统计:统计结果显示,字符“e”、“t”、“a”等在文本中出现的频率较高。
2. 构建霍夫曼树:成功构建了霍夫曼树,树中包含了所有字符及其频率。
3. 生成编码表:根据霍夫曼树生成了字符编码表,频率高的字符分配了较短的编码。
4. 编码数据:使用编码表对文本数据进行编码,成功生成了压缩数据。
信息论综合性实验报告 Huffman编码及译码 代码

Xx大学yy学院综合性设计性实验报告专业班级:学号:姓名:实验所属课程:信息论与编码技术实验室(中心):信息科学与工程学院软件中心指导教师:实验完成时间: 2012 年 12 月 9 日一、设计题目:Huffman编码及译码二、实验内容及要求:<一>实验内容:对所给的字符串进行huffman的编译码;译码对应原始序列,在将编码进行移位操作时,再进行译码输出,得出误码率。
<二>实验要求:自己设计一段信源序列,利用Huffman编码对其进行编码,然后利用相应的译方法进行译码,同时考察译码错误对后续序列带来的影响。
三、实验过程(详细设计):<一> huffman编码原理:Huffman编码是一种紧致编码,但编码序列的码并非是唯一的。
它是根据源数据各信号发生的概率进行编码,在源数据中出现的概率越大的信号,分配的码字越短;出现概率越小的信号,其码字越长,从而达到用尽可能少的码字表示源数据的目的。
Huffman编码的步骤如下:设信源X有m个符号(消息),信源概率分布如下:X = ⎧ x1, x2 ,..., x m ⎫⎩ p1 2 ,..., p m ⎭(1)把信源X 中的消息按概率从大到小的顺序排列;(2)把最后两个出现概率最小的消息合并成一个消息,从而使信源的消息数减少,并同时再按信源符号(消息)出现的概率从大到小排列;(3)重复上述2 个步骤,直到信源最后为一个序列只有一个1;(4)将被整合的消息分别赋予1 和0,并对最后的两个消息也相应地赋予1 和0.(5)通过以上步骤即可完成编码操作。
<二> huffman译码原理:通过在刚开始生成的随机编码序列,得到列出的0 1 序列与源字符串一一对应,就完成了译码。
而对错位后的编码序列,我只是只错位了前两个进行译码,效果不是很明显。
<三>算法设计:1、编码部分:(1)主函数主要用于调用前面所编写的各个函数模块,按照主函数(主函数代码如下)所列出来的调用顺序,进行一一叙述。
霍夫曼编码实验报告(C++)

一、实验名称:霍夫曼编码二、实验环境软件环境:Windows 2000,Microsoft Visual C++6.0硬件环境:P4,2.4GHz,256内存,IBM-PC及兼容机三、实验目的掌握霍夫曼编码、译码原理,并能够通过程序模拟其编码、译码功能。
四、实验原理1、消息按其出现的概率由大到小地排成一个概率序列;2、把概率最小两个消息分成一组,其中一个消息编为0,另一个编为1,然后求其概率和,并把这个新概率与其他尚未处理过的概率重新按概率由大到小排成一个新的概率序列;3、重复步骤,直到所有概率都已联合处理完为止。
五、实验过程与实验结果源程序:#include<iostream>#include<string>using namespace std;#include<math.h>typedef struct{//霍夫曼树的结构体char ch;double weight; //权值,此处为概率int parent,lchild,rchild;}htnode,*hfmtree;typedef char **hfmcode;/*****************************全局变量*****************************/ hfmtree HT;hfmcode HC;int n=0;//霍夫曼树叶节点个数int m=0;//霍夫曼树所有节点个数int *code_length;//用于记录每个消息字符的码长/*****************************霍夫曼编码模块*****************************///对输入的字符进行检验int Input_Char_Check(){int flag=1;int j;for(int i=1;i<n&&flag;i++){for(j=i+1;j<=n;j++)if(HT[j].ch==HT[i].ch){flag=0;break;}}return flag;}//对输入的概率进行检测int Input_Weight_Check(){int flag=0;double sum=0.0;for(int i=1;i<=n;i++){if(!(HT[i].weight>0&&HT[i].weight<1))//概率越界{flag=1;return flag;}else{sum+=HT[i].weight;continue;}}if(sum>1)//概率之和超过1{flag=2;}return flag;}void Select(int a,int *p1,int *p2)/*Select函数,选出HT树到a为止,权值最小和次小且parent为0的2个节点*/{int i,j,x,y;for(j=1;j<=a;++j){if(HT[j].parent==0){x=j;break;}}for(i=j+1;i<=a;++i){if(HT[i].weight<HT[x].weight&&HT[i].parent==0){x=i; //选出权值最小的节点}}for(j=1;j<=a;++j) {if(HT[j].parent==0&&x!=j){y=j;break;}}for(i=j+1;i<=a;++i){if(HT[i].weight<HT[y].weight&&HT[i].parent==0&&x!=i){y=i; //选出权值次小的节点}}if(x>y){*p1=y;*p2=x;}else{*p1=x;*p2=y;}}/*初始化n个叶子节点及其余节点*/void Init_htnode(){int i;char temp_ch;double temp_w;I: cout<<"请输入信源发出的消息字符个数:";cin>>n;if(sizeof(n)!=sizeof(int)||n<=1)//假设输入的不是整数,则报错{cout<<"您输入的数据有误,程序终止!"<<endl;exit(0);}code_length=new int[n+1];for(i=1;i<=n;i++){code_length[i]=0;//初始化码长为0}m=2*n-1;HT=(hfmtree)malloc((m+1)*sizeof(htnode));for(i=1;i<=n;++i) //初始化n个叶子结点{printf("请输入第%d个字符信息:",i);cin>>temp_ch;printf("请输入第%d个字符对应的概率:",i);cin>>temp_w;HT[i].ch=temp_ch;HT[i].weight=temp_w;HT[i].parent=0;HT[i].lchild=0;HT[i].rchild=0;}int flag1=Input_Char_Check();//检测输入的字符是否重复int flag2=Input_Weight_Check();//检测输入的概率是否越界if(!flag1){cout<<"出现相同字符,输入错误,请重新输入!"<<endl;goto I;}if(flag2==1){cout<<"概率越界,输入错误,请重新输入!"<<endl;goto I;}if(flag2==2){cout<<"概率之和超过1,输入错误,请重新输入!"<<endl;goto I;}for(;i<=m;++i) //初始化其余的结点{HT[i].ch='*';//用*表示新生成根节点的字符域HT[i].weight=0;HT[i].parent=0;HT[i].lchild=0;HT[i].rchild=0;}}//建立霍夫曼树void Create_hfmtree(){int i;int p1,p2;//用于记录权值最小及次小节点的下标for(i=n+1;i<=m;++i) //建立霍夫曼树{Select(i-1,&p1,&p2);HT[p1].parent=i;HT[p2].parent=i;HT[i].lchild=p1;HT[i].rchild=p2;HT[i].weight=HT[p1].weight+HT[p2].weight;}}void Hfm_coding() //求出n个字符的霍夫曼编码HC及码长{int i,start;int c;//当前字符下标int f;//当前字符的父节点下标char *cd;HC=(hfmcode)malloc((n+1)*sizeof(char *));cd=(char *)malloc(n*sizeof(char));cd[n-1]='\0';for(i=1;i<=n;++i) //给n个字符编码{start=n-1;for(c=i,f=HT[i].parent;f!=0;c=f,f=HT[f].parent){if(HT[f].lchild==c){cd[--start]='0';}else{cd[--start]='1';}code_length[i]+=1;}HC[i]=(char*)malloc((n-start)*sizeof(char));strcpy(HC[i],&cd[start]);}free(cd);}//初始化/*功能:从终端读入字符集大小n,以及n个字符和n个权值,建立霍夫曼树,并将它存于文件hfmTree中。
霍夫曼编码的实验报告(3篇)

第1篇一、实验目的1. 理解霍夫曼编码的基本原理和实现方法。
2. 掌握霍夫曼编码在数据压缩中的应用。
3. 通过实验,加深对数据压缩技术的理解。
二、实验环境1. 操作系统:Windows 102. 编程语言:C++3. 开发环境:Visual Studio 20194. 数据源:文本文件三、实验原理霍夫曼编码是一种常用的数据压缩算法,适用于无损数据压缩。
它通过使用变长编码表对数据进行编码,频率高的数据项使用短编码,频率低的数据项使用长编码。
霍夫曼编码的核心是构建一棵霍夫曼树,该树是一种最优二叉树,用于表示编码规则。
霍夫曼编码的步骤如下:1. 统计数据源中每个字符的出现频率。
2. 根据字符频率构建一棵最优二叉树,频率高的字符位于树的上层,频率低的字符位于树下层。
3. 根据最优二叉树生成编码规则,频率高的字符分配较短的编码,频率低的字符分配较长的编码。
4. 使用编码规则对数据进行编码,生成压缩后的数据。
5. 在解码过程中,根据编码规则恢复原始数据。
四、实验步骤1. 读取文本文件,统计每个字符的出现频率。
2. 根据字符频率构建最优二叉树。
3. 根据最优二叉树生成编码规则。
4. 使用编码规则对数据进行编码,生成压缩后的数据。
5. 将压缩后的数据写入文件。
6. 读取压缩后的数据,根据编码规则进行解码,恢复原始数据。
7. 比较原始数据和恢复后的数据,验证压缩和解码的正确性。
五、实验结果与分析1. 实验数据实验中,我们使用了一个包含10000个字符的文本文件作为数据源。
在统计字符频率时,我们发现字符“e”的出现频率最高,为2621次,而字符“z”的出现频率最低,为4次。
2. 实验结果根据实验数据,我们构建了最优二叉树,并生成了编码规则。
使用编码规则对数据源进行编码,压缩后的数据长度为7800个字符。
将压缩后的数据写入文件,文件大小为78KB。
接下来,我们读取压缩后的数据,根据编码规则进行解码,恢复原始数据。
比较原始数据和恢复后的数据,发现两者完全一致,验证了压缩和解码的正确性。
编码理论实验报告实验一霍夫曼编码中信息熵及编码效率的实验

编码理论实验报告实验一霍夫曼编码中信息熵及编码效率的实验实验名称实验一霍夫曼编码中信息熵及编码效率的实验一、实验目的1. 掌握霍夫曼编码中信息熵的定义、性质和计算;2. 掌握霍夫曼编码中平均码字长度的定义和计算;3( 掌握霍夫曼编码中编码效率的定义和计算;4. 正确使用C语言实现霍夫曼编码中信息熵、平均码长和编码效率的求取。
二、实验内容1. 熟练列出霍夫曼编码中信息熵、平均码长和编码效率各自的计算公式;2. 正确使用C语言实现计算霍夫曼编码中信息熵、平均码长和编码效率的程序,并在Visual C++环境中验证。
三、实验原理1. 霍夫曼编码的基本原理按照概率大小顺序排列信源符号,并设法按逆顺序分配码字字长,使编码的码字为可辨识的。
2. 平均码长:L=?p(s)*l(单位为:码符号/信源符号) ii其中,p(s)为信源s在q个信源中出现的概率,l为信源s的二进制霍夫曼iiii编码。
3. 信息熵:H(S)=- ?p(s) *log p(s) (单位为:比特/信源符号) i2i其中,p(s)为信源s在q个信源中出现的概率。
ii4. 编码效率:η= H(S)/ L其中,H(S)为信息熵,L为平均码长。
四、实验步骤:1. Huffman编码示例如下图:信源符号概率信源缩减过程编码码长00 0 S1 0.4 0.4 0.4 0.6 00 2 1 0000 1 S2 0.2 0.2 0.4 0.4 10 2 01 1010 01 S3 0.2 0.2 0.2 11 2 11010 11 S4 0.15 0.2 010 3011 S5 0.05 011 3 2. 根据Huffman编码的例子,用C语言完成计算霍夫曼编码中信息熵的程序的编写,并在Visual C++环境中验证;3. 根据Huffman编码的例子,用C语言完成计算霍夫曼编码中平均码长的程序的编写,并在Visual C++环境中验证;4. 根据Huffman编码的例子,用C语言完成计算霍夫曼编码中编码效率的程序的编写,并在Visual C++环境中验证;实验程序:/*********** 霍夫曼编码信息熵、平均码长及编码效率的计算 ************ //按照实验步骤的要求完成程序,正确计算霍夫曼编码的信息熵、 //平均码长以及编码效率,并通过printf函数将三者的计算结果 //打印出来#include<stdio.h>#include<string.h>#include<math.h>#define CH_Num 5 //信源符号个数//主函数void main(){//编程1:定义double型数组gailv存放各信源符号出现的概率double gailv[CH_Num]={0.4,0.2,0.2,0.15,0.05};//编程2:定义int型数组code_len存放各信源符号的霍夫曼编码int code_len[CH_Num]={2,2,2,3,3};//编程3:定义double型变量aver_Len、Hs和code_ratio,分别//对应信息熵、平均码长及编码效率,并初始化为0double aver_Len=0,Hs=0,code_ratio=0;int i;//编程4:利用for循环计算平均码长aver_Lenfor(i=0;i<CH_Num;i++)aver_Len+=gailv[i]*code_len[i];//编程5:利用for循环计算信息熵Hsfor(i=0;i<CH_Num;++i)Hs+=-(gailv[i]*(log(gailv[i])/log(2)));//编程6:计算编码效率code_ratiocode_ratio=Hs/aver_Len;//编程7:利用三条printf语句分别打印平均码长、信息熵和编码效率printf("平均码长=%lf 比特/信源符号\n",aver_Len);printf("信源熵=%lf 码符号/信源符号\n",Hs);printf("编码效率=%lf\n",code_ratio); }运行结果如下图:实验心得:通过本次试验加深了对霍夫曼编码的基本原理的理解以及计算公式的记忆。
信息论与编码实验报告

信息论与编码实验报告一、实验目的1.了解信息论与编码的基本概念和原理。
2.学习如何通过信息论与编码方法实现对数据的压缩和传输。
3.掌握信息论与编码实验的实验方法和实验技能。
4.提高实验设计、数据分析和报告撰写的能力。
二、实验内容1.通过对输入信源进行编码,实现对数据的压缩。
2. 比较不同编码方法的压缩效果,包括Shannon-Fano编码和霍夫曼编码。
3.通过传输信道对编码后的数据进行解码,还原原始信源。
4.分析并比较不同编码方法的传输效果,包括码率和传输质量。
三、实验原理1.信息论:熵是信息论中衡量信源不确定性的指标,熵越小表示信源的可预测性越高,在编码过程中可以压缩数据。
2. 编码方法:Shannon-Fano编码通过分治的方法将输入信源划分为不同的子集,分别进行编码;霍夫曼编码则通过构建最佳二叉树的方式,将较常出现的信源符号编码为较短的二进制码,较少出现的信源符号编码为较长的二进制码。
3.传输信道:信道可能存在误码和噪声,通过差错控制编码可以在一定程度上保障传输数据的正确性和完整性。
四、实验步骤1. 对给定的输入信源进行Shannon-Fano编码和霍夫曼编码。
2.计算编码后的码率,分析不同编码方法的压缩效果。
3.将编码后的数据传输到信道,模拟信道中的误码和噪声。
4.对传输后的数据进行解码,还原原始信源。
5.比较不同编码方法的传输质量,计算误码率和信噪比。
五、实验结果与分析1. 编码结果:通过对输入信源进行编码,得到了Shannon-Fano编码和霍夫曼编码的码表。
2.压缩效果:计算了不同编码方法的码率,比较了压缩效果。
3.传输结果:模拟信道传输后的数据,对数据进行解码,还原原始信源。
4.传输质量:计算了误码率和信噪比,分析了不同编码方法的传输质量。
六、实验总结通过本次实验,我深刻理解了信息论与编码的基本概念和原理,并掌握了信息论与编码实验的实验方法和实验技能。
在实验过程中,我遇到了一些困难,比如对编码方法的理解和实验数据的处理。
霍夫曼信源编码实验报告

实验1:霍夫曼信源编码综合设计【实验目的】通过本专题设计,掌握霍夫曼编码的原理和实现方法,并熟悉利用C语言进行程序设计,对典型的文本数据和图像数据进行霍夫曼编解码。
【预备知识】1、熵的概念,霍夫曼编码原则2、数据结构和算法设计3、C(或C++)编程语言【实验环境】1、设备:计算机一台2、软件:C程序编译器【设计要求】根据霍夫曼编码原则,利用C语言设计并实现霍夫曼编码和解码程序,要求能够对给出的典型文本数据和图像数据进行霍夫曼编解码,并计算相应的熵和压缩比。
【实验原理】Huffman编码属于熵编码的方法之一,是根据信源符号出现概率的分布特性而进行的压缩编码。
Huffman编码的主要思想是:出现概率大的符号用长的码字表示;反之,出现概率小的符号用短的码字表示。
Huffman编码过程描述:1. 初始化:将信源符号按出现频率进行递增顺序排列,输入集合L;2. 重复如下操作直至L中只有1个节点:(a) 从L中取得两个具有最低频率的节点,为它们创建一个父节点;(b) 将它们的频率和赋给父结点,并将其插入L;3. 进行编码:从根节点开始,左子节点赋予1,右节点赋予0,直到叶子节点。
【基本定义】1. 熵和平均编码符号长度熵是信息量的度量方法,它表示某一事件出现的概率越小,则该事件包含的信息就越多。
根据Shannon 理论,信源S 的熵定义为2()log (1/)i i i H s p p =∑,其中i p 是符号i S 在S 中出现的概率;2log (1/)i p 表示包含在i S 中的信息量,也就是编码i S 所需要的位数假设符号i S 编码后长度为l i (i=1,…,n),则平均编码符号长度L 为:i i i L p l =∑ 2. 压缩比设原始字符串的总长度为L orig 位,编码后的总长度为L coded 位,则压缩比R 为 R = (L orig - L coded )/ L orig【例子】有一幅40个象素组成的灰度图像,灰度共有5级,分别用符号A 、B 、C 、D 和E 表示,40个象素中出现灰度A 的象素数有15个,出现灰度B 的象素数有7个,出现灰度C 的象素数有7个等等,如表1所示。
最新《信息论基础》实验报告-实验1

最新《信息论基础》实验报告-实验1实验目的:1. 理解信息论的基本概念,包括信息熵、互信息和编码理论。
2. 通过实验掌握香农信息熵的计算方法。
3. 学习并实践简单的数据压缩技术。
实验内容:1. 数据集准备:选择一段英文文本作为实验数据集,统计各字符出现频率。
2. 信息熵计算:根据字符频率计算整个数据集的香农信息熵。
3. 编码设计:设计一种基于频率的霍夫曼编码方案,为数据集中的每个字符分配一个唯一的二进制编码。
4. 压缩与解压缩:使用设计的霍夫曼编码对原始文本进行压缩,并验证解压缩后能否恢复原始文本。
5. 性能评估:比较压缩前后的数据大小,计算压缩率,并分析压缩效果。
实验步骤:1. 从文本文件中读取数据,统计每个字符的出现次数。
2. 利用统计数据计算字符的相对频率,并转换为概率分布。
3. 应用香农公式计算整个数据集的熵值。
4. 根据字符频率构建霍夫曼树,并为每个字符生成编码。
5. 将原始文本转换为编码序列,并记录压缩后的数据大小。
6. 实现解压缩算法,将编码序列还原为原始文本。
7. 分析压缩前后的数据大小差异,并计算压缩率。
实验结果:1. 原始文本大小:[原始文本大小]2. 压缩后大小:[压缩后大小]3. 压缩率:[压缩率计算结果]4. 霍夫曼编码表:[字符与编码的对应表]实验讨论:- 分析影响压缩效果的因素,如字符集大小、字符频率分布等。
- 讨论在实际应用中,如何优化编码方案以提高压缩效率。
- 探讨信息论在数据压缩之外的其他应用领域。
实验结论:通过本次实验,我们成功地应用了信息论的基本原理,通过霍夫曼编码技术对文本数据进行了有效压缩。
实验结果表明,基于字符频率的霍夫曼编码能够显著减少数据的存储空间,验证了信息论在数据压缩领域的有效性和实用性。
信息论与编码实验报告讲解

信息论与编码实验报告实验课程名称:赫夫曼编码(二进制与三进制编码)专业信息与计算科学班级信息与计算科学1班学生姓名李林钟学号 *************指导老师王老师(3).算法基本步骤描述(4).编码及注解(见附页1) (5).验证截图:得到信源得出信源序列个得出信源序列的计算信源符输输输输输信源符号的赫弗曼码方编码效平均码输编码效率为:(3.3)(4).验证结果截图:() 2.5595.2%2.68H X R η===附页1:#include<stdio.h>#include<string.h>#include<math.h>#define MAX 100//定义全局变量h存放信息熵double h=0;//定义结构体用于存放信源符号,数目及概率typedef struct{//不同的字符char SOURCECODE;//不同字符出现的次数int NUM;//不同字符出现的概率double PROBABILITY;//赫夫曼编码符号int Code[MAX];int start;//赫夫曼树的父结点int parent;//赫夫曼树的左右子结点int lchild;int rchild;//赫夫曼编码的长度int lengthofhuffmancode;}Hcode;Hcode INFORMATION[MAX];//该函数用来求信源所包含的符号,以及不同符号出现的次数和概率int Pofeachsource(char informationsource[MAX],int a){int i,j=1,m,flag=0;char temp;//预先存入第一个字符,便于与后面的字符进行比较//统计不同的字符存入结构体数组中//利用flag标签来标记每个字符是否出现过,若出现过标记为1,否则置为零INFORMATION[0].SOURCECODE=informationsource[0];for(i=1;i<a;i++){ for(m=0;m<i;m++){flag=0;if(informationsource[m]==informationsource[i]){flag=1;break;}}if(flag==1)continue;elseINFORMATION[j++].SOURCECODE=informationsource[i];}INFORMATION[j].SOURCECODE='\0';printf("信源符号数为:%d\n",j);//统计相同的字符出现的次数//每做一个字符出现次数的统计都将结构体数组里的NUM置为零for(i=0;i<j;i++){ INFORMATION[i].NUM=0;for(m=0;m<a;m++)if(informationsource[m]==INFORMATION[i].SOURCECODE)INFORMATION[i].NUM++;}//统计每个字符出现的概率for(i=0;i<j;i++) INFORMATION[i].PROBABILITY=(float)INFORMATION[i].NUM/a;//将每个不同字符出现的次数概率都显示出来for(i=0;i<j;i++)printf("The NUM and PROBABILITY of Code'%c'is %dand %.3f\n",INFORMATION[i].SOURCECODE,INFORMATION[i].NUM,INFORMATION[ i].PROBABILITY);return j;}//求信源符号的熵void H(int a){int i;for(i=0;i<a;i++){h+=((-1)*(INFORMATION[i].PROBABILITY)*(log(INFORMATION[i].PROBABI LITY)/log(2)));}}//赫夫曼编码函数void Huffman(int a){Hcode cd;int i,j,m=0,lm=0,p,c;double min,lmin;//顺序初始化每个信源父子结点为-1for(i=0;i<a;i++){INFORMATION[i].parent=-1;INFORMATION[i].lchild=-1;INFORMATION[i].lchild=-1;}//循环构造Huffman树for(i=0;i<a-1;i++){//min,lmin中存放两个无父结点且结点权值最小的两个结点min=lmin=MAX;//找出所有结点中权值最小、无父结点的两个结点,并合并之为一颗二叉树for (j=0;j<a+i;j++){if((INFORMATION[j].PROBABILITY<min)&&(INFORMATION[j].parent==-1)){lmin=min;lm=m;min=INFORMATION[j].PROBABILITY;m=j;}else if((INFORMATION[j].PROBABILITY<lmin)&&(INFORMATION[j].parent==-1)){lmin=INFORMATION[j].PROBABILITY;lm=j;}}//设置找到的两个子结点 m、lm 的父结点信息INFORMATION[m].parent=a+i;INFORMATION[lm].parent=a+i;INFORMATION[a+i].PROBABILITY=INFORMATION[m].PROBABILITY+INFORMATION[l m].PROBABILITY;INFORMATION[a+i].parent=-1;INFORMATION[a+i].lchild=m;INFORMATION[a+i].rchild=lm;}for (i=0;i<a;i++){cd.start=a-1;c=i;p=INFORMATION[c].parent;while(p!=-1) /* 父结点存在 */{if(INFORMATION[p].lchild==c)cd.Code[cd.start]=1;elsecd.Code[cd.start]=0;cd.start--; /* 求编码的低一位 */c=p;p=INFORMATION[c].parent; /* 设置下一循环条件 */ }//保存求出的每个叶结点的赫夫曼编码和编码的起始位for(j=cd.start+1;j<m;j++){ INFORMATION[i].Code[j]=cd.Code[j];}INFORMATION[i].start=cd.start;}}main(){//定义存放信源符号的数组char informationsource[MAX];int i,j,m;double averageofhuffmancode=0.0,Eita,cV=0.0;printf("please input the source of information:");for(i=0;;i++){scanf("%c",&informationsource[i]);if(informationsource[i]=='\n')break;}informationsource[i]='\0';printf("信源序列为:");//显示已输入的一串信源符号puts(informationsource);//返回不同信源符号的数目m=Pofeachsource(informationsource,i);//求信源的符号熵H(m);printf("信源的符号熵:H(X)=%.3f(比特/符号)\n",h);Huffman(m);//输出已保存好的所有存在编码的赫夫曼编码for(i=0;i<m;i++){printf("%c's Huffman code is: ",INFORMATION[i].SOURCECODE); for(j=INFORMATION[i].start+1;j<m;j++)printf("%d",INFORMATION[i].Code[j]);INFORMATION[i].lengthofhuffmancode=m-INFORMATION[i].start-1; printf("\n");}//求赫夫曼编码的平均码长和编码效率for(i=0;i<m;i++)averageofhuffmancode+=INFORMATION[i].PROBABILITY*INFORMATION[i].l engthofhuffmancode;printf("赫夫曼编码的平均码长为:%lf(码元/信源符号)\n",averageofhuffmancode);Eita=h/averageofhuffmancode;printf("赫夫曼编码的编码效率为:%lf\n",Eita);//求赫弗曼编码的码方差for(i=0;i<m;i++)cV+=INFORMATION[i].PROBABILITY*INFORMATION[i].lengthofhuffmancode *INFORMATION[i].lengthofhuffmancode;cV-=averageofhuffmancode*averageofhuffmancode;printf("赫弗曼编码的码方差为:%lf\n",cV);}附页2#include <iostream.h>#include <math.h>#include <string.h>#include <stdio.h>#include <stdlib.h>#include <vector> //为了使用vector容器using namespace std; ///vector属于std命名域,因此使用全局命名域方式struct Huffman_InformationSource //信源类型{char InformationSign[10]; //信源符号double Probability; //概率char Code[10]; //编码结果int CodeLength; //码长};struct HuffNode //赫夫曼树的节点类型{char InformationSign[10];double Probability;HuffNode *LeftSubtree,*middleSubtree,*RightSubtree,*Next;char Code[10];int CodeLength;};class CHuffman_3 //三进制赫夫曼编码{public:CHuffman_3() //初始化{ISNumber=0;AvageCodeLength=0.0;InformationRate=0.0;CodeEfficiency=0.0;}~CHuffman_3(){DestroyBTree(HuffTree);}void Huffman_Input(); //输入信息void Huffman_Sort(); //排序void Huffman_Tree(); //构造赫夫曼树void Huffman_Coding(); //生成赫夫曼编码void Huffman_CodeAnalyzing(); //结果分析void Huffman_Display(); //显示结果信息void DestroyBTree(HuffNode *TreePointer); //释放资源private:vector<Huffman_InformationSource>ISarray; //声明ISarray数组,初始时为空int ISNumber; //符号个数double AvageCodeLength; //平均码长double InformationRate; //信息率double CodeEfficiency; //编码效率HuffNode * HuffTree; //赫夫曼树private:void Huffman_Code(HuffNode *TreePointer);};//输入信源信息如果需要添加信源信息在这里修改即可void CHuffman_3::Huffman_Input(){Huffman_InformationSource temp1={"A",0.40,"",0};ISarray.push_back(temp1);Huffman_InformationSource temp2={"B",0.18,"",0};ISarray.push_back(temp2);Huffman_InformationSource temp3={"C",0.10,"",0};ISarray.push_back(temp3);Huffman_InformationSource temp4={"D",0.10,"",0};ISarray.push_back(temp4);Huffman_InformationSource temp5={"E",0.07,"",0};ISarray.push_back(temp5);Huffman_InformationSource temp6={"F",0.06,"",0};ISarray.push_back(temp6);Huffman_InformationSource temp7={"G",0.05,"",0};ISarray.push_back(temp7);Huffman_InformationSource temp8={"H",0.04,"",0};ISarray.push_back(temp8);ISNumber=ISarray.size();}//按概率“从大到小”排序:void CHuffman_3::Huffman_Sort(){Huffman_InformationSource temp;int i,j;for(i=0;i<ISNumber-1;i++)for(j=i+1;j<ISNumber;j++)if(ISarray[i].Probability<ISarray[j].Probability){temp=ISarray[i];ISarray[i]=ISarray[j];ISarray[j]=temp;}}//基于ISarray数组构造赫夫曼树void CHuffman_3::Huffman_Tree(){int i;HuffNode *ptr1,*ptr2,*ptr3,*ptr4,*temp1,*temp2;//(1):基于数组,创建单向链表ptr1=new HuffNode;strcpy(ptr1->InformationSign,ISarray[0].InformationSign);ptr1->Probability=ISarray[0].Probability;strcpy(ptr1->Code,ISarray[0].Code);ptr1->LeftSubtree=NULL;ptr1->middleSubtree =NULL;ptr1->RightSubtree=NULL;ptr1->Next=NULL;HuffTree=ptr1; //赋给数据成员HuffTree for(i=1;i<ISNumber;i++){ptr2=new HuffNode;strcpy(ptr2->InformationSign,ISarray[i].InformationSign);ptr2->Probability=ISarray[i].Probability;strcpy(ptr2->Code,ISarray[i].Code);ptr2->LeftSubtree=NULL;ptr2->middleSubtree =NULL;ptr2->RightSubtree=NULL;ptr2->Next=ptr1;ptr1=ptr2;}//结果:链表的表头为数组的最小元素。
信息论和编码实验报告

信息论与编码实验报告实验课程名称:赫夫曼编码(二进制与三进制编码)专业信息与计算科学班级信息与计算科学1班学生姓名李林钟学号 20####指导老师王老师信息论和编码实验报告一、实验目的利用赫夫曼编码进行通信可以大大提高通信利用率,缩短信息传输时间,降低传输成本。
赫夫曼编码是信源编码中最基本的编码方法。
●理解赫夫曼编码,无论是二进制赫夫曼编码,还是m 进制赫夫曼编码,都要理解其编码原理和编码步骤。
● 回顾无失真信源编码定理,理解无失真编码的基本原理和常用编码方法。
●掌握二进制赫夫曼编码和m 进制赫夫曼编码的基本步骤,能计算其平均码长,编码效率等。
●应用二进制赫夫曼编码或m 进制赫夫曼编码处理简单的实际信源编码问题。
二、实验环境与设备1、操作系统与编程软件:windows 操作系统,cfree5.0, Visual C++ 6.0。
2、编程语言:C 语言以及C++语言 三、实验内容1. 二进制赫夫曼编码原理及步骤: (1)信源编码的计算设有N 个码元组成的离散、无记忆符号集,其中每个符号由一个二进制码字表示,信源符号个数n 、信源的概率分布P={p(s i )},i=1,…..,n 。
且各符号xi 的以li 个码元编码,在变长字编码时每个符号的平均码长为∑==ni li xi p L 1)( ;信源熵为:)(log )()(1xi p xi p X H ni ∑=-= ;唯一可译码的充要条件:11≤∑=-ni Ki m ;其中m 为码符号个数,n 为信源符号个数,Ki 为各码字长度。
(2)二元霍夫曼编码规则(1)将信源符号依出现概率递减顺序排序。
(2)给两个概率最小的信源符号各分配一个码位“0”和“1”,将两个信源符号合并成一个新符号,并用这两个最小的概率之和作为新符号的概率,结果得到一个只包含(n-1)个信源符号的新信源。
称为信源的第一次缩减信源,用s1 表示。
(3)将缩减信源 s1 的符号仍按概率从大到小顺序排列,重复步骤(2),得到只含(n-2)个符号的缩减信源s2。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验名称实验一霍夫曼编码中信息熵及编码效率的实验
一、实验目的
1. 掌握霍夫曼编码中信息熵的定义、性质和计算;
2. 掌握霍夫曼编码中平均码字长度的定义和计算;
3.掌握霍夫曼编码中编码效率的定义和计算;
4. 正确使用C语言实现霍夫曼编码中信息熵、平均码长和编码效率的求取。
二、实验内容
1. 熟练列出霍夫曼编码中信息熵、平均码长和编码效率各自的计算公式;
2. 正确使用C语言实现计算霍夫曼编码中信息熵、平均码长和编码效率的程序,并在Visual C++环境中验证。
三、实验原理
1. 霍夫曼编码的基本原理
按照概率大小顺序排列信源符号,并设法按逆顺序分配码字字长,使编码的码字为可辨识的。
2. 平均码长:L=∑p(s i)*l i (单位为:码符号/信源符号)
其中,p(s i)为信源s i在q个信源中出现的概率,l i为信源s i的二进制霍夫曼编码。
3. 信息熵:H(S)=- ∑p(s i) *log2 p(s i) (单位为:比特/信源符号)
其中,p(s i)为信源s i在q个信源中出现的概率。
4. 编码效率:η= H(S)/ L
其中,H(S)为信息熵,L为平均码长。
四、实验步骤:
1. Huffman编码示例如下图:
2. 根据Huffman 编码的例子,用C 语言完成计算霍夫曼编码中信息熵的程序的编写,并在Visual C++环境中验证;
3. 根据Huffman 编码的例子,用C 语言完成计算霍夫曼编码中平均码长的程序的编写,并在Visual C++环境中验证;
4. 根据Huffman 编码的例子,用C 语言完成计算霍夫曼编码中编码效率的程序的编写,并在Visual C++环境中验证;
实验程序:
/*********** 霍夫曼编码信息熵、平均码长及编码效率的计算 ************ //按照实验步骤的要求完成程序,正确计算霍夫曼编码的信息熵、
//平均码长以及编码效率,并通过printf 函数将三者的计算结果
//打印出来
#include<stdio.h>
#include<string.h>
#include<math.h>
#define CH_Num 5 //信源符号个数
//主函数
void main()
{
//编程1:定义double 型数组gailv 存放各信源符号出现的概率
double gailv[CH_Num]={0.4,0.2,0.2,0.15,0.05};
//编程2:定义int 型数组code_len 存放各信源符号的霍夫曼编码 int code_len[CH_Num]={2,2,2,3,3};
//编程3:定义double 型变量aver_Len 、Hs 和code_ratio ,分别
//对应信息熵、平均码长及编码效率,并初始化为0
S1 S2 S3 S4 S5 概率 0.05 0.4 0.2 0.2 0.15 信源缩减过程 0.4 0.2 0.2 0.2 0.4 0.4 0.2 0.6 0.4 编码 011 00 10 11 010 码长 3
2 2 2 3
00 10 11
010 011 10 11 01
00 01 00 1
1 0 信源符号
double aver_Len=0,Hs=0,code_ratio=0;
int i;
//编程4:利用for循环计算平均码长aver_Len
for(i=0;i<CH_Num;i++)
aver_Len+=gailv[i]*code_len[i];
//编程5:利用for循环计算信息熵Hs
for(i=0;i<CH_Num;++i)
Hs+=-(gailv[i]*(log(gailv[i])/log(2)));
//编程6:计算编码效率code_ratio
code_ratio=Hs/aver_Len;
//编程7:利用三条printf语句分别打印平均码长、信息熵和编码效率 printf("平均码长=%lf 比特/信源符号\n",aver_Len);
printf("信源熵=%lf 码符号/信源符号\n",Hs);
printf("编码效率=%lf\n",code_ratio);
}
运行结果如下图:
实验心得:通过本次试验加深了对霍夫曼编码的基本原理的理解以及计算公式的记忆。
并使用C语言实现计算霍夫曼编码中信息熵、平均码长和编码效率的程序,并在Visual C++环境中验证,且结果正确。