实验一 香农编码和Huffman编码
优秀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; %记录两个最小概率相加得到的值在新排序中的位置。
Huffman编码实验报告
图像Huffman编码实验报告
1 实验目的
(1)熟练掌握Huffman编码的方法;
(2)理解无失真信源编码和限失真编码方法在实际图像信源编码应用中的差异。
2 实验内容与步骤
(1)针对“image1.bmp”、“image2.bmp”和“image3.bmp”进行灰度频率统计(即计算图像灰度直方图),在此基础上添加函数代码构造Huffman码表,针对图像数据进行Huffman编码,观察和分析不同图像信源的平均码长、编码效率和压缩比。
(2)针对任意一幅图像,得到其差分图像,对差分图像统计灰度频率,进行Huffman编码,计算平均码长、编码效率和压缩比,并与(1)对比。
3 实验结果
(1)对图像数据进行Huffman 编码,得到不同图像信源的平均码长、编码效率和压缩比如下:
image1:5.960179 0.994678 1.342242
image2:4.443604 0.992368 1.800341
image3:6.733643 0.996281 1.188064
(2)对lenna.bmp 进行Huffman 编码,得到其平均码长、编码效率和压缩比分别是:
5.294220 0.994358 1.511082。
编码理论实验报告
一、实验目的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。
数据结构实验实验报告Huffman赫夫曼编码及应用
实验报告课程名称:数据结构实验名称:赫夫曼编码及应用院(系):计算机与通信工程学院专业班级:计算机科学与技术姓名:学号:指导教师:2020 年 5 月12 日一、实验目的掌握赫夫曼树和赫夫曼编码的基本思想和算法的程序实现。
二、实验内容及要求1、任务描述a.提取原始文件中的数据(包括中文、英文或其他字符),根据数据出现的频率为权重,b.构建Huffman编码表;c.根据Huffman编码表对原始文件进行加密,得到加密文件并保存到硬盘上;d.将加密文件进行解密,得到解码文件并保存点硬盘上;e.比对原始文件和解码文件的一致性,得出是否一致的结论。
2、主要数据类型与变量a.对Huffman树采用双亲孩子表示法,便于在加密与解密时的操作。
typedef struct Huffman* HuffmanTree;struct Huffman{unsigned int weight; //权值unsigned int p, l, r;//双亲,左右孩子};b.对文本中出现的所有字符用链表进行存储。
typedef struct statistics* List;struct statistics {char str; //存储此字符int Frequency; //出现的频率(次数)string FinalNum; //Huffman编码struct statistics* Next;};3、算法或程序模块对读取到的文本进行逐字符遍历,统计每个字符出现的次数,并记录在创建的链表中。
借助Huffman树结构,生成结构数组,先存储在文本中出现的所有字符以及它们出现的频率(即权值),当作树的叶子节点。
再根据叶子节点生成它们的双亲节点,同样存入Huffman树中。
在完成对Huffman树的创建与存储之后,根据树节点的双亲节点域以及孩子节点域,生成每个字符的Huffman编码,并存入该字符所在链表节点的FinalNum域。
huffman编码C语言实验报告
Huffman编码数学系李一鹏PB12001076 第五组1.实验题目:huffman编码2.实验目的:熟悉二叉树操作,掌握huffman编码思想。
3.实验内容:任盈盈要传授给令狐冲读心大法,她深色庄重地递给令狐冲一张貌似剑谱的那啥。
令狐冲一看,蒙了,这……这是啥?擦,01010001101010111010101001010010101011101110?任盈盈说,其实人类内心的微小波动都可以通过读心术转化为0和1,只是人类会想得太多,我们如果需要迅速辨认出别人所想,必先有一个简单的01序列。
令狐冲很想知道小师妹在想些什么,但是…令狐冲的脑袋你懂的,请大家编一个程序满足这人渣男主吧…4.算法思想:先把每个结点以树的形式储存在数组中,每次选择两个权值最小的两颗树合并成一个树加入数组,操作时只需要判断父结点是否为空即可判断其是否可合并。
5.程序清单:#include<stdio.h>#include<stdlib.h>#define new1 (ht*)malloc(sizeof(ht))typedef struct huffmantree{char data;int weight;struct huffmantree *left,*right,*parent;}ht;char s[20],a[128][128],b[128];int maxdepth;ht *huffmancreate(){//创建huffman树ht *p[256],*p1,*p2;FILE *f1;int c[128]={0},k=0,j,i,min1,min2;char d;f1=fopen("article.txt","r");while(1){d=fgetc(f1);if(feof(f1))break;c[d]++;}//统计字符数目fclose(f1);for(i=0;i<128;i++)//生成n个叶结点if(c[i]){p[k]=new1;p[k]->weight=c[i];p[k]->data=i;p[k]->left=0;p[k]->right=0;p[k]->parent=0;k++;}for(i=k;i<=2*(k-1);i++){//生成根结点和n-2个枝结点p[i]=new1;p[i]->parent=0;p[i]->data=6;//枝结点和根结点用黑桃表示min2=min1=32767;for(j=0;j<i;j++)if(!p[j]->parent)if(p[j]->weight<min1){min2=min1;p2=p1;min1=p[j]->weight;p1=p[j];}else if(p[j]->weight<min2){min2=p[j]->weight;p2=p[j];}p[i]->left=p1;p[i]->right=p2;p1->parent=p[i];p2->parent=p[i];p[i]->weight=min1+min2;}return p[i-1];//返回根结点}void fwh(ht *p,int i){//用递归进行huffman编码int j;char c;if(p->left){s[i]=48;fwh(p->left,i+1);s[i]=49;fwh(p->right,i+1);}else{putchar(p->data);putchar(9);//输出结点名c=p->data;b[c]=i;for(j=0;j<i;j++){putchar(s[j]);a[c][j]=s[j];}//输出编码putchar(10);}}void depth(int i,ht *p){//求一棵树的深度if(p){if(i>maxdepth)maxdepth=i;depth(i+1,p->left);depth(i+1,p->right);}}int forwardspace(ht *p){//求最左边结点到左屏幕的空格数int i,fs;for(i=0;p;p=p->left)i++;for(fs=0;i<maxdepth;i++)fs=fs*2+1;return fs;}void writeln(ht*p){//输出树int i,a[20],pow2[20],front,rear,fs,nowd,nown,num[200],d[200];//num[i]:第i 个结点在拓展二叉树中的序号,nown:前一个输出的结点序号,d[i]:第i个结点的层数,nowd:当前层数ht *queue[200];depth(1,p);a[maxdepth+1]=1;for(i=maxdepth;i>=1;i--) a[i]=2*a[i+1];//求第i行两结点的空格数+1pow2[1]=1;for(i=2;i<=maxdepth;i++) pow2[i]=pow2[i-1]*2;//2的i-1次方front=rear=0;fs=forwardspace(p);queue[++rear]=p;d[rear]=1;num[rear]=1;nowd=0;nown=0;while(front<rear){//层次遍历并输出二叉树p=queue[++front];//出队if(d[front]>nowd){nowd++;putchar(10);for(i=1;i<=a[nowd]/2-1+(num[front]-pow2[nowd])*a[nowd]-fs;i++)putchar(3 2);//输出每行的第一个结点}elsefor(i=1;i<=(num[front]-nown)*a[nowd]-1;i++)putchar(32);//输出该行的其余结点putchar(p->data);nown=num[front];if(p->left){queue[++rear]=p->left;d[rear]=nowd+1;num[rear]=nown*2;}//左结点入队if(p->right){queue[++rear]=p->right;d[rear]=nowd+1;num[rear]=nown*2+1;} //右结点入队}putchar(10);}void transfer(){//编码FILE *f1,*f2;char d,i;f1=fopen("article.txt","r");f2=fopen("transfer_article.txt","w");while(1){d=fgetc(f1);if(feof(f1))break;for(i=0;i<b[d];i++)fputc(a[d][i],f2);}fclose(f1);fclose(f2);}void antitransfer(ht *head){//解码FILE *f1;ht *p;char c;f1=fopen("transfer_article.txt","r");while(1){p=head;while(p->left){c=fgetc(f1);if(feof(f1))break;if(c==48)p=p->left;else p=p->right;}if(feof(f1))break;putchar(p->data);}putchar(10);fclose(f1);}main(){ht *head;head=huffmancreate();printf("These are the huffman code creating form the article.txt:\n");fwh(head,0);printf("Here is the huffman tree:");writeln(head);transfer();printf("Here is the article antitransfer from the transfer_article.txt:\n");antitransfer(head);}6.运行结果:(1):(2):7.调试分析:设计实验时在树的输出上用了较多时间,为了美观而靠左输出树,但叶结点一旦多于20个就没辙了,所以没给出第一个运行结果的树的输出。
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-------进⾏译码。
哈夫曼编码(HuffmanCoding)
哈夫曼编码(HuffmanCoding)
哈夫曼编码(Huffman Coding),又称霍夫曼编码,是一种编码方式,可变字长编码(VLC)的一种。
Huffman于1952年提出一种编码方法,该方法完全依据字符出现概率来构造异字头的平均长度最短的码字,有时称之为最佳编码,一般就叫做Huffman编码(有时也称为霍夫曼编码)。
哈夫曼编码,主要目的是根据使用频率来最大化节省字符(编码)的存储空间。
简易的理解就是,假如我有A,B,C,D,E五个字符,出现的频率(即权值)分别为5,4,3,2,1,那么我们第一步先取两个最小权值作为左右子树构造一个新树,即取1,2构成新树,其结点为1+2=3,如图:
虚线为新生成的结点,第二步再把新生成的权值为3的结点放到剩下的集合中,所以集合变成{5,4,3,3},再根据第二步,取最小的两个权值构成新树,如图:
再依次建立哈夫曼树,如下图:
其中各个权值替换对应的字符即为下图:
所以各字符对应的编码为:A->11,B->10,C->00,D->011,E->010
霍夫曼编码是一种无前缀编码。
解码时不会混淆。
其主要应用在数据压缩,加密解密等场合。
如果考虑到进一步节省存储空间,就应该将出现概率大(占比多)的字符用尽量少的0-1进行编码,也就是更靠近根(节点少),这也就是最优二叉树-哈夫曼树。
数据结构课程设计哈夫曼编码实验
数据结构设计性实验Huffman编码与译码学号姓名班级设计性实验—Huffman 编码与译码一.实验目的:在掌握相关基础知识的基础上,学会自己设计实验算法,熟练掌握Huffman 树的建立方法,Huffman 编码的方法,进而设计出Huffman 译码算法,并编程实现。
二.实验要求:在6学时以内,制作出能够实现基于26个英文字母的任意字符串的编译码。
写出技术工作报告并附源程序。
三.实验内容及任务:1.设字符集为26个英文字母,其出现频度如下表所示。
2.建Huffman 树; 3.利用所建Huffman 树对任一字符串文件进行编码——即设计一个Huffman 编码器;4.对任一字符串文件的编码进行译码——即设计一个Huffman 译码器。
实现步骤:1.数据存储结构设计; 2.操作模块设计; 3.建树算法设计; 4.编码器设计;5. 译码器设计;51 48 1 15 63 57 20 32 5 1频度z y x w v u t 字符11611882380频度p 21 f q15 g r 47 h s o n m l k j 字符 57 103 32 22 13 64 186 频度 i e d c b a 空格 字符四.分析以及算法描述1.分析问题1)首先学习二叉树的知识,了解二叉树的路径、权数以及带权路径长度计算。
2)认识霍夫曼树,了解霍夫曼树的定义,构造霍夫曼树构造算法①又给定的n个权值{w1,w2,w3,……,w n}构造根节点的二叉树,从而得到一个二叉树森林F={T1,T2,T3,……T n}。
②在二叉树森里选取根节点全职最小和此最小的两棵二叉树作为左右节点构造新的二叉树,此时新的二叉树的根节点权值为左右子树权值之和。
③在二叉树森林中删除作为新二叉树的根节点左右子树的两棵二叉树,将新的二叉树加入到二叉树森林F中。
④重复②和③,当二叉树森林F只剩下一棵二叉树时,这棵二叉树是所构造的霍夫曼树。
3)练习通过普通树来构造霍夫曼树。
试验五. Huffman编码问题
试验五. Huffman编码问题一实验原理Huffman是一种被广泛应有并且十分有效的压缩技术,一般可以压缩至20%-90%,Huffman 是一种贪心算法,根据次算法可以将字符表示称二进制形式.Huffman最早给出了一个带有规律的算法,俗称Huffman算法:1)将n个带权值wi(i≤n)的结点构成n棵二叉树的集合T={T1,T2,……,Tn},每棵二叉树只有一个根结点,其左右子树均为空;2)在T中选取两个权值最小的结点作为左右子树,构成一个新的二叉树,其根结点的权值取左右子树权值之和;3)在T中删除这两棵树,将新构成的树加入到T中;4)重复2)、3)步的操作,直到T中只含一棵树为止,该树就是Huffman树。
二实验目的本次实验主要目的就是实现Huffman算法并且进行验证三实验过程定义节点数据结构信息:typedef struct{char letter;int weight;int parent;int lchild;int rchild;}HTNode,*HuffmanTree;建立Huffman树的代码:void Select(HuffmanTree &HT,int i,int &s1,int &s2){/*选择森林中,根结点的权值最小和次小的两个树,*将其根结点的下标号记入s1和s2中*/int j, k;for(k = 1; k < i; k++){if(HT[k].parent != NULL)continue;s1 = k;/*init the number*/break;}for(j = 1; j < i; j++){if(HT[j].parent != NULL)continue;if(HT[j].weight < HT[s1].weight)s1 = j;}for(k = 1; k <= i; k++){if(HT[k].parent != NULL || k == s1)continue;s2 = k;break;}for(j = 1; j < i; j++){if(HT[j].parent != NULL)continue;if(HT[j].weight <= HT[s2].weight && j != s1)s2 = j;}}根据Huffman树构造的Huffman编码主要代码void HuffmanCoding(HuffmanTree &HT,HuffmanCode &HC,char *zi,int *w,int n) {HuffmanTree p;int m,i,s1,s2,f,c;int Istart = 1;char *cd;if(n <= 1)return;m = 2*n-1;if(!(HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode))))exit(OVERFLOW);for(p=HT+1,i=1;i<=n;++i,++zi,++p,++w){/*生成独立的森林*/p->parent = NULL;p->letter = *zi;p->lchild = NULL;p->rchild = NULL;p->weight = *w;}for(;i<=m;++i,++p){(*p).weight=0;(*p).parent=0;(*p).lchild=0;(*p).rchild=0;}for(i=n+1;i<=m;++i){Select(HT,i-1,s1,s2);HT[s1].parent=i;HT[s2].parent=i;HT[i].lchild=s1;HT[i].rchild=s2;HT[i].weight=HT[s1].weight+HT[s2].weight;}HC=(HuffmanCode)malloc((n+1)*sizeof(char *));cd=(char*)malloc(n*sizeof(char));/*临时的code存储*/ cd[n-1]='\0';for(i=1;i<=n;++i){Istart = n - 1;/*按已生成的哈夫曼树,得到各个字符的哈夫曼编码*/for(c = i, f = HT[i].parent; f != 0; c = f, f = HT[f].parent) if(HT[f].lchild == c)cd[--Istart] = '0';elsecd[--Istart] = '1';HC[i] = (char *)malloc((n - Istart) * sizeof(char));strcpy(HC[i], &cd[Istart]);}free(cd);}四实验结果根据代码运行得到实验结果如下:。
Huffman编码实验报告
Huffman编码实验报告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。
0.0.0.0.1.000.0.0.00.0.0.0.(4)重复上述步骤,直至缩减信源只剩两个符号为止,此时所剩两个符号 的概率之和必为 1,然后从最后一级缩减信源开始,依编码路径向前返回,就得到各信源符号所对应的码字。
2 功能介绍输入一段字符序列,通过本程序可得出该字符序列中各个字符出现的次数,以及每个字符出现的概率,并能计算出信源符号熵,每个字符的哈弗曼编码,和相应的平均码长,编码效率,码方差。
3 算法基本步骤描述4 C 语言源代码#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;}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;}}void 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);}5 运行结果截图:6 实验分析(1)在哈弗曼编码的过程中,对缩减信源符号按概率有大到小的顺序重新排列,应使合并后的新符号尽可能排在靠前的位置,这样可使合并后的新符号重复编码次数减少,使短码得到充分利用。
实验 Huffman编码(含matlab代码)
实验二Huffman编码一实验目的1 通过本实验实现信源编码——Huffman编码2 编写M文件实现,掌握Huffman编码方法二实验要求1 了解matlab中M文件的编辑、调试过程2 编写程序实现Huffman编码算法三实验步骤1 输入Huffman编码程序2 运行程序,按照提示输入相应信息,并记录输入信息,及运行结果。
注:观察结果方法:data(1).Code显示a1的编码,同理显示data(2).Code,a2的编码结果。
3 思考:该程序编出的Huffman码是否是最小码方差的码?为什么?四报告要求五附Huffman编码程序clearN=input('请输入信源符号的个数:') ;for i=1:N%data(1).name=input('请输入各信源符号的名称:');data(i).p=input('请输入各信源符号发生的概率:');endfor i=1:Npp(i)=data(i).p;data(i).imap=i; %各符号在编码过程中的指针data(i).Code=''; %各符号的编码结果endfor j = 1:N % N——信源符号的个数for i = 1:N - jif (pp(i) > pp(i + 1))fT = pp(i);pp(i) = pp(i + 1);pp(i + 1) = fT;for k = 1:Nif data(k).imap == idata(k).imap = i + 1;elseif data(k).imap == i + 1data(k).imap = i;endendendendendp=pp;%%%%%%%%%%%%%%%%%%%%% %// 计算哈夫曼编码表%// 开始编码for i=1:N-1for k = 1:Nif data(k).imap== idata(k).Code = strcat('1',data(k).Code);elseif (data(k).imap== i + 1)data(k).Code = strcat('0',data(k).Code);endendp(i + 1) = p(i + 1)+p(i);for k = 1:Nif (data(k).imap == i)data(k).imap = i + 1;endendfor j = i + 1:N-1if p(j) >p(j + 1)fT =p(j);p(j) = p(j + 1);p(j + 1) = fT;for k = 1:Nif (data(k).imap == j)data(k).imap = j + 1;elseif (data(k).imap == j + 1)data(k).imap = j;endendendendend。
huffman实验报告
一、问题描述1. 实验题目:huffman编解码2. 基本要求:初始化(I nitialization)。
从终端读入字符集大小n,以及n个字符和n个权值,建立Huffman 树,并将它存入hfmTree 中。
编码(E ncoding)。
利用已经建好的Huffman树(如果不在内存,则应从文件hfmTree 中读取),对文件ToBeTran中的正文进行编码,然后将结果存入文件CodeFile中。
解码(D ecoding)。
利用已经建立好的Huffman树将文件CodeFile中的代码进行解码,结果存入TextFile中。
打印代码文件(Print)。
将文件CodeFile以紧凑的格式显示在终端上,每行 50 个代码。
同时将此字符形式的编码文件写入文件CodePrint中。
打印Huffman树(T ree Printing)。
将已经在内存中的Huffman树以直观的形式(树或者凹入的形式)显示在终端上,同时将此字符形式的Huffman 树写入文件TreePrint中。
3. 测试数据:用下表给出的字符集和频度的实际统计数据建立Huffman树,并对以下报文进行编字符集大小 n,n个字符和 n个权值均从终端读入,初始化后的huffman树存储在hfmTree文件中,待编码文件为ToBeTran,编码结果以文本的方式存储在文件CodeFile中,解码文件存在TextFile中,打印的编码和赫夫曼树分别存储在CodePrint和TreePrint文件中。
用户界面可以设计为“菜单”方式:显示上述功能符号,再加上一个退出功能“Q”,表示退出(quit)。
用户键入一个选择功能符,此功能执行完毕后再显示此菜单,直至某次用户选择了Q为止。
二、需求分析1. 本程序可以根据输入字符集和频度建立huffman树并且对给定文本进行编解码,还可以直接读入建立好的huffman树再对给定文本编解码,打印编码、解码结果、表格形式及树形的huffman树。
信息论霍夫曼、香农-费诺编码
信息论霍夫曼、香农-费诺编码LT二、实验原理:1、香农-费诺编码首先,将信源符号以概率递减的次序排列进来,将排列好的信源符号划分为两大组,使第组的概率和近于相同,并各赋于一个二元码符号”0”和”1”.然后,将每一大组的信源符号再分成两组,使同一组的两个小组的概率和近于相同,并又分别赋予一个二元码符号。
依次下去,直至每一个小组只剩下一个信源符号为止。
这样,信源符号所对应的码符号序列则为编得的码字。
译码原理,按照编码的二叉树从树根开始,按译码序列进行逐个的向其叶子结点走,直到找到相应的信源符号为止。
之后再把指示标记回调到树根,按照同样的方式进行下一序列的译码到序列结束。
如果整个译码序列能够完整的译出则返回成功,否则则返回译码失败。
2、霍夫曼编码霍夫曼编码属于码词长度可变的编码类,是霍夫曼在1952年提出的一种编码方法,即从下到上的编码方法。
同其他码词长度可变的编码一样,可区别的不同码词的生成是基于不同符号出现的不同概率。
生成霍夫曼编码算法基于一种称为“编码树”(coding tree)的技术。
算法步骤如下:(1)初始化,根据符号概率的大小按由大到小顺序对符号进行排序。
(2)把概率最小的两个符号组成一个新符号(节点),即新符号的概率等于这两个符号概率之和。
(3)重复第2步,直到形成一个符号为止(树),其概率最后等于1。
(4)从编码树的根开始回溯到原始的符号,并将每一下分枝赋值为1,上分枝赋值为0。
三、实验环境matlab7.1四、实验内容1、对于给定的信源的概率分布,用香农-费诺编码实现图像压缩2、对于给定的信源的概率分布,用霍夫曼编码实现图像压缩五、实验过程1.香农-费诺编码编码1function c=shannon(p)%p=[0.2 0.15 0.15 0.1 0.1 0.1 0.1 0.1] %shannon(p)[p,index]=sort(p)p=fliplr(p)n=length(p)pa=0for i=2:npa(i)= pa(i-1)+p(i-1) endk=ceil(-log2(p))c=cell(1,n)for i=1:nc{i}=”tmp=pa(i)for j=1:k(i)tmp=tmp*2if tmp>=1tmp=tmp-1 c{i(j)='1'elsec{i}(j) = '0' endendendc = fliplr(c)c(index)=c编码2clc;clear;A=[0.4,0.3,0.1,0.09,0.07,0.04]; A=fliplr(sort(A));%降序排列[m,n]=size(A);for i=1:nB(i,1)=A(i);%生成B的第1列end%生成B第2列的元素a=sum(B(:,1))/2;for k=1:n-1ifabs(sum(B(1:k,1))-a)<=abs(sum(B(1:k+1, 1))-a)break;endendfor i=1:n%生成B第2列的元素if i<=kB(i,2)=0;elseB(i,2)=1;endend%生成第一次编码的结果END=B(:,2)';END=sym(END);%生成第3列及以后几列的各元素j=3;while (j~=0)p=1;while(p<=n)x=B(p,j-1);for q=p:nif x==-1break;elseif B(q,j-1)==xy=1;continue;elsey=0;break;endendif y==1q=q+1;endif q==p|q-p==1B(p,j)=-1;elseif q-p==2B(p,j)=0;END(p)=[char(END(p)),'0'];B(q-1,j)=1;END(q-1)=[char(END(q-1)),'1']; elsea=sum(B(p:q-1,1))/2;for k=p:q-2abs(sum(B(p:k,1))-a)<=abs(sum(B(p:k+1, 1))-a);break;endendfor i=p:q-1if i<=kB(i,j)=0;END(i)=[char(END(i)),'0'];elseB(i,j)=1;END(i)=[char(END(i)),'1'];endendendendendC=B(:,j);D=find(C==-1);[e,f]=size(D);if e==nj=0;elsej=j+1;endendBAENDfor i=1:n[u,v]=size(char(END(i))); L(i)=v;avlen=sum(L.*A)2. 霍夫曼编码function c=huffman(p)n=size(p,2)if n==1c=cell(1,1)c{1}=''returnend[p1,i1]=min(p)index=[(1:i1-1),(i1+1:n)] p=p(index)n=n-1[p2,i2]=min(p)index2=[(1:i2-1),(i2+1:n)] p=p(index2);i2=index(i2)index=index(index2)p(n)=p1+p2c=huffman(p)c{n+1}=strcat(c{n},'1')c{n}=strcat(c{n},'0') index=[index,i1,i2]c(index)=c。
霍夫曼编码的实验报告(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哈夫曼编码实验的目的是掌握哈夫曼编码的原理,掌握哈夫曼树的生成方法。
了解数据压缩。
实验要求实现Huffman编解码器生成算法。
三。
实验内容首先统计待压缩文件中出现的字符和字母的数量,根据字符字母和空格的概率对其进行编码,然后读取要编码的文件并将其存储在另一个文件中;然后调用已编码的文件,对输出进行解码,最后存储到另一个文件中。
5实验原理1。
假设树的权值是用huffn树的定义来构造的。
每个加权叶为wi,权值路径最小的二叉树成为Huffman树或最优二叉树。
Huffman树的结构:权重是一个输入频率的数组,这些值根据节点对象中的数据属性按顺序分配给HTs,即每个HT节点对应一个输入频率。
然后,根据数据属性,从最小值到最大值取两个最小值和这个小HT节点,将它们的数据相加,构造一个新的htnode作为它们的父节点。
指针parentleftchild和rightchild被分配了相应的值。
将这个新节点插入最小堆。
按照这个程序,我们能建一棵树吗?通过构造的树,从下至上搜索父节点,直到父节点成为树的顶点。
这样,每次向上搜索后,根据原始节点是父节点的左子节点还是右子节点记录1或0。
每一个01都有一个完整的编码,每一个都有一个完整的编码。
初始化,以文本文件中的字符数为权值,生成Huffman树,按符号概率由大到小对符号进行排序,概率最小的两个符号形成一个节点。
重复步骤()(),直到概率和为1,从根节点到每个符号对应的“叶”,概率高的符号标为“0”,概率低的符号从根节点开始,对符号7进行编码。
实验程序ා include<iostream>ා include<iomanip>ා include<iomanip>使用命名空间STD;typedef struct//节点结构{char data;//记录字符值long int weight;//记录字符权重unsigned int parent,lchild,rchild;}Htnode,*HuffmanTree;typedef char**huffmancode;//dynamicly allocate array to store Huffman code table void select(HuffmanTree&HT,int i,int&S1,int&S2)//选择HT[1中权重最小且父节点不为0的两个节点。
霍夫曼及香农-范诺编码方法
1.霍夫曼编码方法:先按出现的概率大小排队,把两个最小的概率相加,作为
新的概率和剩余的概率重新排队,再把最小的两个概率相加,再重新排队,直到最后变成1。
每次相加时都将“0”和“1”赋与相加的两个概率,读出时由该符号开始一直走到最后的”0”或者“1”,将路线上所遇到的“0”和“1”按最低位到最高位的顺序排好,就是该符号的霍夫曼编码。
低位高位
用霍夫曼编码所得的平均码长为:Σ(码长×出现概率)
上例为:
0.2×2+0.19×2+0.18×3+0.17×3+0.15×3+0.1×4+0.01×4=2.72 bit
可以算出本例的信源熵为2.61bit,二者已经是很接近了。
2.香农-范诺编码的目的是产生具有最小冗余的码词。
其基本思想是产生编码长度可变的码词。
估计码词长度的准则是符号出现的概率,符号出现的概率越大,其码词的长度越短。
香农-范诺编码方法:将符号从最大可能到最少可能排序,将排列好的信源符号分化为两大组,使两组的概率和近于相同,并各赋予一个二元码符号“0”和“1”。
只要组内有两个或两个以上符号,就以同样的方法重复以上分组,以此确定这些符号的连续编码数字。
依次下去,直至每一组只剩下一个信源符号为止。
香农-范诺编码算法步骤:
(1)按照符号出现的概率减少的顺序将待编码的符号排成序列。
(2)将符号分成两组,使这两组符号概率和相等或几乎相等。
(3)将第一组赋值为0,第二组赋值为1。
(4)对每一组,重复步骤2的操作,直至每一组只剩下一个信源符号为止。
哈夫曼编码 实验报告
哈夫曼编码实验报告哈夫曼编码实验报告一、引言哈夫曼编码是一种用于数据压缩的算法,由大卫·哈夫曼于1952年提出。
它通过将出现频率高的字符用较短的编码表示,从而实现对数据的高效压缩。
本实验旨在通过实际操作和数据分析,深入了解哈夫曼编码的原理和应用。
二、实验目的1. 掌握哈夫曼编码的基本原理和算法;2. 实现哈夫曼编码的压缩和解压缩功能;3. 分析不同数据集上的压缩效果,并对结果进行评估。
三、实验过程1. 数据集准备本实验选取了三个不同的数据集,分别是一篇英文文章、一段中文文本和一段二进制数据。
这三个数据集具有不同的特点,可以用来评估哈夫曼编码在不同类型数据上的压缩效果。
2. 哈夫曼编码实现在实验中,我们使用了Python编程语言来实现哈夫曼编码的压缩和解压缩功能。
首先,我们需要统计数据集中各个字符的出现频率,并构建哈夫曼树。
然后,根据哈夫曼树生成每个字符的编码表,将原始数据转换为对应的编码。
最后,将编码后的数据存储为二进制文件,并记录编码表和原始数据的长度。
3. 压缩效果评估对于每个数据集,我们比较了原始数据和压缩后数据的大小差异,并计算了压缩比和压缩率。
压缩比是指压缩后数据的大小与原始数据大小的比值,压缩率是指压缩比乘以100%。
通过对比不同数据集上的压缩效果,我们可以评估哈夫曼编码在不同类型数据上的性能。
四、实验结果与分析1. 英文文章数据集对于一篇英文文章,经过哈夫曼编码压缩后,我们发现压缩比为0.6,即压缩后的数据只有原始数据的60%大小。
这说明哈夫曼编码在英文文本上具有较好的压缩效果。
原因在于英文文章中存在大量的重复字符,而哈夫曼编码能够利用字符的出现频率进行编码,从而减少数据的存储空间。
2. 中文文本数据集对于一段中文文本,我们发现哈夫曼编码的压缩效果不如在英文文章上的效果明显。
压缩比为0.8,即压缩后的数据只有原始数据的80%大小。
这是因为中文文本中的字符种类较多,并且出现频率相对均匀,导致哈夫曼编码的优势减弱。
Huffman编码实验报告
Huffman编码实验报告⼀、实验⽬的1.掌握树的操作实现算法。
2.掌握⼆叉树的建⽴,遍历,输出等算法。
3.掌握哈夫曼树的构造算法。
⼆、实验要求:(1)实验前编写源程序、准备测试数据。
(2)在Turbo C下完成程序的编辑、编译、运⾏,获得程序结果。
如果结果有误,应找出原因,并设法更正之。
三、实验内容编程实现任给n个权值,构造出哈夫曼树,并对各个字符编码。
#include#define MAXBIT 100#define MAXVALUE 10000#define MAXLEAF 30#define MAXNODE MAXLEAF*2 -1typedef struct{int bit[MAXBIT];int start;} HCodeType; /* 编码结构体*/typedef struct{int weight; /*权重*/int parent; /*⽗节点*/int lchild; /*左孩⼦*/int rchild; /*右孩⼦*/} HNodeType; /* 结点结构体*//* 构造⼀颗哈夫曼树*/void HuffmanTree (HNodeType HuffNode[MAXNODE], int n){ /* i、j:循环变量,m1、m2:构造哈夫曼树不同过程中两个最⼩权值结点的权值,x1、x2:构造哈夫曼树不同过程中两个最⼩权值结点在数组中的序号。
*/int i, j, m1, m2, x1, x2;/* 初始化存放哈夫曼树数组HuffNode[] 中的结点*/for (i=0; i<2*n-1; i++){ HuffNode[i].weight = 0; /*权重初始化为0*/HuffNode[i].parent =-1; /*节点初始化为-1*/HuffNode[i].lchild =-1;HuffNode[i].lchild =-1;} /* end for *//* 输⼊n 个叶⼦结点的权值*/for (i=0; i{ printf ("Please input weight of leaf node %d: \n", i);/*窗⼝弹出输⼊命令,输⼊权重值*/scanf ("%d", &HuffNode[i].weight);} /* end for *//* 循环构造Huffman 树*/for (i=0; i{ m1=m2=MAXVALUE; /* m1、m2中存放两个⽆⽗结点且结点权值最⼩的两个结点*/ x1=x2=0;/* 找出所有结点中权值最⼩、⽆⽗结点的两个结点并合并之为⼀颗⼆叉树*/ for (j=0; j {if (HuffNode[j].weight < m1 && HuffNode[j].parent==-1)/*判断节点的权重及是否有⽗节点*/{ m2=m1; /*将m1,x1的值赋给m2,x2*/x2=x1;m1=HuffNode[j].weight;/*当前节点的权重赋给m1*/x1=j;/*当前节点序号赋给x1*/}else if (HuffNode[j].weight < m2 && HuffNode[j].parent==-1)/*判断节点的权重及是否有⽗节点*/{ m2=HuffNode[j].weight;/*当前节点的权重赋给m2*/x2=j;/*当前节点序号赋给x2*/}} /* end for *//* 设置找到的两个⼦结点x1、x2 的⽗结点信息*/HuffNode[x1].parent = n+i;/*设置⽗节点的序号*/HuffNode[x2].parent = n+i;HuffNode[n+i].weight = HuffNode[x1].weight + HuffNode[x2].weight;/*设置⽗节点的权值*/HuffNode[n+i].lchild = x1;/*设置⽗节点对应的左右孩⼦*/HuffNode[n+i].rchild = x2;printf ("x1.weight and x2.weight in round %d: %d, %d\n", i+1,HuffNode[x1].weight, HuffNode[x2].weight); /* ⽤于测试*/printf ("\n");} /* end for */} /* end HuffmanTree */int main(void){ HNodeType HuffNode[MAXNODE]; /* 定义⼀个结点结构体数组*/HCodeType HuffCode[MAXLEAF], cd; /* 定义⼀个编码结构体数组,同时定义⼀个临时变量来存放求解编码时的信息*/ int i, j, c, p, n;printf ("Please input n:\n");/*窗⼝弹出输⼊命令,输⼊权值*/scanf ("%d", &n);HuffmanTree (HuffNode, n);/*调⽤构造哈夫曼树的函数*/for (i=0; i < n; i++){ cd.start = n-1;c = i;p = HuffNode[c].parent;while (p != -1) /* ⽗结点存在*/{ if (HuffNode[p].lchild == c)/*处理左孩⼦节点*/cd.bit[cd.start] = 1;else /*处理右孩⼦节点*/cd.bit[cd.start] = 0;cd.start--; /* 求编码的低⼀位*/c=p;p=HuffNode[c].parent; /* 设置下⼀循环条件*/ } /* end while *//* 保存求出的每个叶结点的哈夫曼编码和编码的起始位*/ for (j=cd.start+1; j{ HuffCode[i].bit[j] = cd.bit[j];}HuffCode[i].start = cd.start;} /* end for *//* 输出已保存好的所有存在编码的哈夫曼编码*/for (i=0; i{printf ("%d 's Huffman code is: ", i);for (j=HuffCode[i].start+1; j < n; j++){printf ("%d", HuffCode[i].bit[j]);}printf ("\n");}return 0;}四、实验数据记录及分析运⾏程序,依据提⽰输⼊权值,然后依次输⼊各个值得权重,即可得到哈夫曼编码后的⼆进制码字。
实验1 Huffman编码生成器-matlab
1.计算机
2.Windows 2000或以上
3.MatLab
四、实验原理
Huffman编码算法
为使平均码长最短,必须使最后一步缩减信源有m个信源符号。如果第一步给概率最小的符号分配码元时,所取的符号数就不一定是m个。
对于m进制编码,若所有码字构成全树,可分离的码字数必为m+k(m-1),式中k为非负整数,即缩减次数。
% L为编码返回的平均码字长度,q为编码效率%
%*****************************************%
function [W,L,q]=huffman(P)
if (length(find(P<=0))~=0)
error('Not a prob.vector,negative component'); %判断是否符合概率分布条件
% H为信息熵%
%******************************%
function H=entropy(P,r)
if (length(find(P<=0))~=0)
error('Not a prob.vector,negative component'); %判断是否符合概率分布条件
end
s2='Huffman编码平均码字长度L:';
s3='Huffman编码的编码效率q:';
disp(s0);
disp(s1),disp(B),disp(W);
disp(s2),disp(L);
disp(s3),disp(q);
%函数说明:%
% H=entropy(P,r)为信息熵函数%
实验四 图像编码实验——霍夫曼编码、香农-弗诺编码及行程编码
实验四图像编码实验——霍夫曼编码、香农-弗诺编码及行程编码一、实验条件PC机数字图像处理实验教学软件大量样图二、实验目的1、熟悉图像霍夫曼编码和香农-弗诺编码的基本原理,了解编程实现的具体步骤,观察编码表,比较编码效率;2、熟悉图像行程编码的的基本原理,了解PCX文件的结构及利用行程编解码实现PCX文件存取的具体过程,比较编码前后的图像;3、了解LZW编解码、GIF文件结构和预测DPCM编解码的基本原理,观察图像编解码效果。
三、实验原理1、霍夫曼编码和香农-弗诺编码的基本原理及编程实现步骤关于霍夫曼编码和香农-弗诺编码的基本原理可以查阅实验系统中的相关文字说明,这里只介绍编程实现的程序流程图,以霍夫曼编码为例:2、行程编码的的基本原理及PCX文件的结构行程编码(Run Length Coding,RLC)的原理非常简单:将图像每行中灰度值相同的相邻象素用一个计数值和该灰度值来代替。
例如:aaaabbccccd,可以表示为4a2b4c1d。
如果图像中存在大面积灰度值相同的区域,那么采用行程编码的效率是惊人的,但是如果图像中每个相邻点的灰度值各不相同,此时用行程编码不但不能压缩,反而会使图像数据大幅度增加。
PCX格式文件采用行程编码进行图像压缩。
PCX文件结构非常简单,仅分为文件头和图像压缩数据两个部分(如果是256色文件,则还要有一个256色调色板存于文件尾部),本系统涉及的PCX文件包括文件头、图像像据和调色板三部分。
PCX文件结构的详细信息可以查阅有关书籍,这里不再赘述。
四、实验内容霍夫曼编码香农-弗诺编码行程编解码及PCX文件存取:从图库中选择图像, 执行图像编码→行程编解码→存为PCX文件, 指定文件名并保存。
执行图像编码→行程编解码→读取PCX文件,打开刚刚保存的PCX文件,比较解码图像和原图像, 结合直方图观察解码图像和原图像的差影图像, 分析并说明行程编码的特点, 指出行程编码在什么情况下的压缩效率最高。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验一 香农编码和Huffman 编码
一、实验目的
进一步熟悉香农编码和Huffman 编码过程,掌握matlab 语言递归程序的设计和调试技术。
二、实验要求
1.已知信源符号个数和信源的概率分布,要求写出香农和Huffman 的代码,输出每个信源符号对应的香农和Huffman 编码的码字。
2.以一组信源码字为例,给出输出码字,并求出编码效率。
三、基本原理
● 香农编码:
编码规则如下:
1.将信源消息符号按其出现的概率大小排列
1()p x ≥2()p x ≥···≥()n p x
2.确定满足下列不等式的整数码长Ki :
2l o g ()i
p x -≤i K <2log ()i p x -+1 3.为了编成唯一可译码,计算第i 个消息的累加概率
Pi=1
1
()i k k p x -=∑
4.将累加概率Pi 变换成二进制数。
5.取Pi 二进数的小数点后Ki 位即为该消息符号的二进制码数。
● Huffman 编码:
1.将n 个信源消息符号按其出现的概率大小依次排列,
1()p x ≥2()p x ≥···≥()n p x
2.取两个概率最小的字母分别配以0和1两码元,并将这两个概率相加作为一个新字母的概率,与未分配的二进符号的字母重新排队。
3.对重排后的两个概率最小符号重复步骤(2)的过程。
4.不断继续上述过程,直到最后两个符号配以0和1为止。
5.从最后一级开始,向前返回得到各个信源符号所对应的码元序列,即相应的码字。
四、实验报告内容
1.描述所用算法,给出代码。
2.与其他编码方式相比,香农和Huffman 编码各有何优缺点,其压缩效率如何?。