Matlab函数实现哈夫曼编码算法

合集下载

编码理论实验报告

编码理论实验报告

一、实验目的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。

matlab 霍夫曼编码

matlab 霍夫曼编码

matlab 霍夫曼编码一、背景介绍二、霍夫曼编码原理三、matlab实现霍夫曼编码1. 建立霍夫曼树2. 构建编码表3. 压缩文件4. 解压文件四、应用举例一、背景介绍在信息传输和存储中,数据的压缩是一个重要的问题。

其中,霍夫曼编码是一种常用的无损压缩算法,通过对不同字符出现频率进行编码,可以将数据压缩到较小的空间中。

在matlab中,可以通过代码实现对数据的霍夫曼编码。

二、霍夫曼编码原理1. 需要进行压缩的数据由若干个字符组成。

2. 统计每个字符出现的频率,并根据频率构建霍夫曼树。

3. 根据霍夫曼树构建每个字符对应的编码表。

4. 将原始数据中每个字符按照对应的编码表进行编码,并将所有编码拼接为一个字符串。

5. 将字符串转换为二进制数列,并将其写入文件中。

解压时,需要读取二进制数列,并按照相应的编码表进行解码还原原始数据。

三、matlab实现霍夫曼编码1. 建立霍夫曼树在matlab中,可以通过以下代码实现霍夫曼树的构建:```matlabfunction [T, f] = huffmantree(p)n = length(p);f = p;T = zeros(n-1, 3);for i=1:n-1[f, j] = sort(f);T(i, 1:2) = j(1:2);T(i, 3) = f(1) + f(2);f(2) = T(i, 3);end```其中,p为每个字符出现的频率,n为字符数。

函数返回的T为霍夫曼树的结构矩阵,f为每个节点的权值。

2. 构建编码表在得到霍夫曼树之后,可以通过以下代码构建每个字符对应的编码表:```matlabfunction codebook(T)n = size(T, 1) + 1;codebook = cell(n, 2);for i=1:ncodebook{i, 1} = i;endfor i=1:n-1j = T(i, 1:2);for k=1:length(j)codebook{j(k), 2}=[codebook{j(k), 2},num2str(mod(k-1,2))]; if ~isempty(codebook{j(k), 2})codebook{j(k), 3}=[codebook{j(k), 3},i];elsecodebook{j(k), 3}=i;endendend```其中,codebook为编码表,第一列为字符编号,第二列为对应的编码。

哈夫曼编码算法实现完整版

哈夫曼编码算法实现完整版

实验三树的应用一.实验题目:树的应用——哈夫曼编码二.实验内容:利用哈夫曼编码进行通信可以大大提高信道的利用率,缩短信息传输的时间,降低传输成本。

根据哈夫曼编码的原理,编写一个程序,在用户输入结点权值的基础上求哈夫曼编码。

要求:从键盘输入若干字符及每个字符出现的频率,将字符出现的频率作为结点的权值,建立哈夫曼树,然后对各个字符进行哈夫曼编码,最后打印输出字符及对应的哈夫曼编码。

三、程序源代码:#include <iostream.h>#include <fstream.h>#include <string.h>#include <stdlib.h>typedef struct{char data;int weight;int parent,lchild,rchild;}HTNode,*HuffmanTree;typedef char * * HuffmanCode;void Select(HuffmanTree &HT,int n,int m){HuffmanTree p=HT;int tmp;for(int j=n+1;j<=m;j++){int tag1,tag2,s1,s2;tag1=tag2=32767;for(int x=1;x<=j-1;x++){ if(p[x].parent==0&&p[x].weight<tag1){ tag1=p[x].weight;s1=x;}}for(int y=1;y<=j-1;y++){ if(p[y].parent==0&&y!=s1&&p[y].weight<tag2){ tag2=p[y].weight;s2=y;}}if(s1>s2) //将选出的两个节点中的序号较小的始终赋给s1{ tmp=s1; s1=s2; s2=tmp;}p[s1].parent=j;p[s2].parent=j;p[j].lchild=s1;p[j].rchild=s2;p[j].weight=p[s1].weight+p[s2].weight;}}void HuffmanCoding(HuffmanTree &HT,int n,char *w1,int*w2){int m=2*n-1;if(n<=1) return;HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode));HuffmanTree p=HT;for(int i=1;i<=n;i++){ p[i].data=w1[i-1];p[i].weight=w2[i];p[i].parent=p[i].lchild=p[i].rchild=0;}for(;i<=m;i++){ p[i].weight=p[i].parent=p[i].lchild=p[i].rchild=0; }Select(HT,n,m);ofstream outfile; //生成hfmTree文件outfile.open("hfmTree.txt",ios::out);for (i=1;i<=m;i++){outfile<<HT[i].weight<<"\t"<<HT[i].parent<<"\t"<<HT[i].lchild<<"\t"<<HT[i].rchild<<"\t"<<endl;}outfile.close();cout<<"初始化结果已保存在hfmTree文件中\n";}void ToBeTree() //将正文写入文件ToBeTree中{ofstream outfile;outfile.open("ToBeTree.txt",ios::out);outfile<<"THIS PROGRAM IS MYFA VORITE";outfile.close();}void Encoding(HuffmanTree &HT,int n) //编码{HuffmanCode HC;HC=(HuffmanCode)malloc((n+1)*sizeof(char *));char *cd;cd=(char *)malloc(n*sizeof(char));cd[n-1]='\0';for(int k=1;k<=n;k++){ int start=n-1;for(int c=k,f=HT[k].parent;f!=0;c=f,f=HT[f].parent){ if(HT[f].lchild==c) cd[--start]='0';else cd[--start]='1';}HC[k]=(char *)malloc((n-start)*sizeof(char));strcpy(HC[k],&cd[start]);}cout<<"输出哈夫曼编码:"<<endl;for(int h=1;h<=n;h++) //输出编码{ cout<<HT[h].data<<":";cout<<HC[h];cout<<" ";if (h%8==0) cout<<endl;}cout<<endl<<"输出正文编码:"<<endl;ToBeTree();//读取TOBETREE文件里的正文,并进行编码fstream infile;infile.open("ToBeTree.txt",ios::in);char s[80];while(!infile.eof()){infile.getline(s,sizeof(s));}infile.close();fstream outfile;outfile.open("CodeFile.txt",ios::out);int count=0;for (h=0;s[h]!='\0';h++){ for(k=1;k<=n;k++)if (s[h]==HT[k].data){ cout<<HC[k];cout<<" ";count++;outfile<<HC[k];break;}if (count%9==0) cout<<endl; //每输出7个换行}outfile.close();cout<<"\n编码结果已保存在文件CodeFile中.";cout<<endl;}void Decoding(HuffmanTree &HT,int n) //译码{int f=2*n-1;fstream infile;infile.open("CodeFile.txt",ios::in);char s[1000];while(!infile.eof()){infile.getline(s,sizeof(s));}infile.close();int i=0;int j=0;fstream outfile;outfile.open("TextFile.txt",ios::out);while(s[i]!='\0'){ f=2*n-1;while(HT[f].lchild!=0)//以f对应的节点的左孩子的值==0作为结束{if (s[j]=='0') f=HT[f].lchild;else f=HT[f].rchild;j++;}i=j;cout<<HT[f].data;outfile<<HT[f].data;}outfile.close();cout<<"\n译码结果已保存在文件TextFile中.";cout<<endl;}void Print() //印代码文件{ int count=0;fstream infile;infile.open("CodeFile.txt",ios::in);char s[1000];while(!infile.eof()){infile.getline(s,sizeof(s));for(int i=0;s[i]!='\0';i++){ cout<<s[i];count++;if (count%50==0) cout<<endl; //在终端上每行显示50个代码}}infile.close();cout<<endl;}char menu() //菜单函数{ cout<<"功能菜单如下:"<<endl;cout<<"* * * * * * * * * * * * * * * * * * * * *"<<endl;cout<<" I:初始化(Initialization) "<<endl;cout<<" E:编码(Encoding) "<<endl;cout<<" D:译码(Decoding) "<<endl;cout<<" P:印代码文件(Print) "<<endl;cout<<" Q:退出(Exit) "<<endl;cout<<"* * * * * * * * * * * * * * * * * * * * *"<<endl;cout<<"请输入功能字符:";char ch;cin>>ch;return ch;}void main(){ int n;int Array[100];char cArray[100];HuffmanTree HT;cout<<"输入n个字符:";cin.getline(cArray,100);n=strlen(cArray);cout<<"一共"<<n<<"个字符.\n";cout<<"依次输入各个字符的权值:"<<endl;for (int i=1;i<=n;i++) cin>>Array[i];int tag;char x=menu();while(1){ switch (x){case 'I':HuffmanCoding(HT,n,cArray,Array);break;case 'E':Encoding(HT,n);break;case 'D':Decoding(HT,n);break;case 'P':Print();break;case 'Q':tag=0;cout<<"结束"<<endl;break;default:cout<<"你输入错误!"<<endl;}if(tag==0) break;cout<<"y(继续) or n(退出)"<<endl;char ch;cin>>ch;if (ch=='y'){ cout<<"请输入功能字符:";char c;cin>>c;x=c;}else exit(1);}}测试数据:用下表给出的字符集和频度的实际统计数据建立哈夫曼树,并实现以下报文的译码和编码:"THIS PROGRAM IS MY FAVORITE".字符空格 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四.测试结果:如图一所示五.实验体会通过本次实验,尤其在自己对程序的调试过程中,感觉对树的存储结构,终结状态,还有编码,译码的过程都有了比较清晰的认识。

实验六、统计压缩编码

实验六、统计压缩编码
举个例子:假设一个文件中出现了 8 种符号 S0,S1,S2,S3,S4,S5,S6,S7,那么 每种符号要编码,至少需要 3 比特。假设编码成 000,001,010,011,100,101,110,111(称 做 码 字 ) 。 那 么 符 号 序 列 S0S1S7S0S1S6S2S2S3S4S5S0S0S1 编 码 后 变 成 000001111000001110010010011100101000000001,共用了 42 比特。我们发现 S0,S1,S2 这 三个符号出现的频率比较大,其它符号出现的频率比较小,如果我们采用一种编码方案使得 S0,S1,S2 的码字短,其它符号的码字长,这样就能够减少占用的比特数。例如,我们采
end y=B(n,j+1); END(t-1)=[char(END1(y)),'0']; END(t)=[char(END1(y)),'1']; t=t+1; END1=END; end A%排序后的原概率序列 END%编码结果 for i=1:n [a,b]=size(char(END(i))); L(i)=b; end
end B;%输出编码表
END1=sym('[0,1]');%给最后一列的元素编码 END=END1; t=3; d=1; for j=n-2:-1:1%从倒数第二列开始依次对各列元素编码
for i=1:t-2 if i>1 & B(i,j)==B(i-1,j) d=d+1; else d=1; end B(B(n,j+1),j+1)=-1; temp=B(:,j+1); x=find(temp==B(i,j)); END(i)=END1(x(d));

信息论与编码实验报告

信息论与编码实验报告

实验一 绘制二进熵函数曲线(2个学时)一、实验目的:1. 掌握Excel 的数据填充、公式运算和图表制作2. 掌握Matlab 绘图函数3. 掌握、理解熵函数表达式及其性质二、实验要求:1. 提前预习实验,认真阅读实验原理以及相应的参考书。

2. 在实验报告中给出二进制熵函数曲线图三、实验原理:1. Excel 的图表功能2. 信源熵的概念及性质()()[]()[]())(1)(1 .log )( .)( 1log 1log )(log )()(10 , 110)(21Q H P H Q P H b nX H a p H p p p p x p x p X H p p p x x X P X i i i λλλλ-+≥-+≤=--+-=-=≤≤⎩⎨⎧⎭⎬⎫-===⎥⎦⎤⎢⎣⎡∑单位为 比特/符号 或 比特/符号序列。

当某一符号xi 的概率p(xi)为零时,p(xi)log p(xi) 在熵公式中无意义,为此规定这时的 p(xi)log p(xi) 也为零。

当信源X 中只含有一个符号x 时,必有p(x)=1,此时信源熵H (X )为零。

四、实验内容:用Excel 和Matlab 软件制作二进熵函数曲线。

根据曲线说明信源熵的物理意义。

(一) Excel具体步骤如下:1、启动Excel 应用程序。

2、准备一组数据p 。

在Excel 的一个工作表的A 列(或其它列)输入一组p ,取步长为0.01,从0至100产生101个p (利用Excel 填充功能)。

3、取定对数底c,在B列计算H(x) ,注意对p=0与p=1两处,在B列对应位置直接输入0。

Excel中提供了三种对数函数LN(x),LOG10(x)和LOG(x,c),其中LN(x)是求自然对数,LOG10(x)是求以10为底的对数,LOG(x,c)表示求对数。

选用c=2,则应用函数LOG(x,2)。

在单元格B2中输入公式:=-A2*LOG(A2,2)-(1-A2)*LOG(1-A2,2)双击B2的填充柄,即可完成H(p)的计算。

哈夫曼编码算法实现

哈夫曼编码算法实现

哈夫曼编码(Huffman Coding)是一种常见的数据压缩算法,它通过构建哈夫曼树(Huffman Tree)来实现。

以下是一个简单的哈夫曼编码算法的实现示例,使用Python 语言:pythonCopy codeimport heapqfrom collections import defaultdictclass HuffmanNode:def __init__(self, char, frequency):self.char = charself.frequency = frequencyself.left = Noneself.right = Nonedef __lt__(self, other):return self.frequency < other.frequencydef build_huffman_tree(data):frequency = defaultdict(int)for char in data:frequency[char] += 1priority_queue = [HuffmanNode(char, freq) for char, freq in frequency.items()]heapq.heapify(priority_queue)while len(priority_queue) > 1:node1 = heapq.heappop(priority_queue)node2 = heapq.heappop(priority_queue)merged_node = HuffmanNode(None, node1.frequency + node2.frequency)merged_node.left = node1merged_node.right = node2heapq.heappush(priority_queue, merged_node)return priority_queue[0]def build_huffman_codes(root, current_code="", codes={}):if root:if root.char is not None:codes[root.char] = current_codebuild_huffman_codes(root.left, current_code + "0", codes)build_huffman_codes(root.right, current_code + "1", codes)return codesdef huffman_encoding(data):if not data:return None, Noneroot = build_huffman_tree(data)codes = build_huffman_codes(root)encoded_data = "".join([codes[char] for char in data])return encoded_data, rootdef huffman_decoding(encoded_data, root):if not encoded_data or not root:return Nonecurrent_node = rootdecoded_data = ""for bit in encoded_data:if bit == "0":current_node = current_node.leftelse:current_node = current_node.rightif current_node.char is not None:decoded_data += current_node.charcurrent_node = rootreturn decoded_data# 示例data = "abracadabra"encoded_data, tree_root = huffman_encoding(data) decoded_data = huffman_decoding(encoded_data, tree_root)print("Original data:", data)print("Encoded data:", encoded_data)print("Decoded data:", decoded_data)。

编写matlab函数实现huffman编码的算法

编写matlab函数实现huffman编码的算法
1 i N , Ri 被称为量化间隔,且在每个区域内选择一个点作量化级数。这样落
在区域内的随机变量的所有值都被量化为第 i 个量化级数,用 X i 来表示,这就意 味着:
x Ri ( x) xi
显而易见,这类量化引入了失真,其均方误差为:
d i 1 ( x xi ) 2 f x( x)dx

这称为 Kraft 不等式。
q
i 1
r li 1
(8)
由上式可知,给定 r 和 q,只要允许码字长度可以足够长,则码长总可以满 足 Kraft 不等式而得到即时码,Kraft 不等式指出了即时码的码长必须满足的条 件。后来 McMillan 证明对于唯一可译码得码长也必须满足此不等式。在码长的 选择上唯一可译码并不比即时码有更宽松的条件。对于唯一可译码,该不等式又 称为 McMillan 不等式。 唯一可译码存在的充要条件是:
展信源进行编码, 当 N 趋向于无穷时, 平均码长可以趋进该极限值。 还可以证明, 如果我们不确切知道信源的概率分布,我们用估计的概率分布去进行编码时,平 均码长会加长,但是如果估计的偏差不大的话,平均码长也不会增加太多。 2.4 无失真编码算法 2.4.1 无失真信源编码定理 设单符号、离散、无记忆信源的熵为 H(S),若用二进制码对其做变字长、非 续长编码,一定可以找到一种编码方式,其平均码长满足:

q
i 1
r li 1
(9)
其中 r 为码符号个数,为码字长度,q 为信源符号个数 无失真变长信源编码定理 离散无记忆信源 S 的 N 次扩展信源 S N ,其熵为 H (S N ) ,并且编码器的码元 符号集为 A : {a1 , a2 ,..., aq } 对信源 S N 进行编码,总可以找到一种编码方法,构成唯 一可译码,使信源 S 中每个符号 Si 所需要的平均码长满足

Matlab函数实现哈夫曼编码算法讲解

Matlab函数实现哈夫曼编码算法讲解

------------------------------------------------------------精品文档--------------------------------------------------------函数实现哈夫曼编码的算法编写Matlab 设计目的和意义一、在数字信号的处理和传数字信号充斥着各个角落。

在当今信息化时代,一个信源编码的好坏优劣直接影响到了信源编码是首先遇到的问题,输中,成为了大如何使编码的效率最高,后面的处理和传输。

如何无失真地编码,家研究的对象。

它由哈夫曼编码是一种变长的编码方案。

哈夫曼编码就是其中的一种,码元内容为到根结点的路径中与父结点的最优二叉树既哈夫曼树得到编码,可以根所以哈夫曼在编码在数字通信中有着重要的意义。

左右子树的标识。

既实现了信源的无失真地据信源符号的使用概率的高低来确定码元的长度。

编码,又使得编码的效率最高。

设计原理二、哈夫曼编码(Huffman Coding)是一种编码方式,哈夫曼编码是可变字长编码(VLC)的一种。

uffman于1952年提出一种编码方法,该方法完全依据字符出现概率来构造异字头的平均长度最短的码字,有时称之为最佳编码,一般就叫作Huffman 编码。

而哈夫曼编码的第一步工作就是构造哈夫曼树。

哈夫曼二叉树的构造方法原则如下,假设有n个权值,则构造出的哈夫曼树有n个叶子结点。

n个权值分别设为w1、w2、…、wn,则哈夫曼树的构造规则为:(1) 将w1、w2、…,wn看成是有n 棵树的森林(每棵树仅有一个结点);(2) 在森林中选出两个根结点的权值最小的树合并,作为一棵新树的左、右子树,且新树的根结点权值为其左、右子树根结点权值之和;从森林中删除选取的两棵树,并将新树加入森林;(3).步,直到森林中只剩一棵树为止,该树即为所求得的哈(3)(2)(4)、重复夫曼树。

具体过程如下图1产所示:(例)图1 哈夫曼树构建过程哈夫曼树构造成功后,就可以根据哈夫曼树对信源符号进行哈夫曼编码。

matlab霍夫曼编码函数

matlab霍夫曼编码函数

matlab霍夫曼编码函数Matlab是一个广泛应用于科学计算和工程领域的高级计算机语言和环境。

它提供了各种函数和工具箱,可用于解决各种数学问题和实现不同的算法。

霍夫曼编码是一种数据压缩算法,它通过将频率最高的字符编码为较短的比特串,从而实现对数据的有效压缩。

在本文中,我们将介绍如何在Matlab中实现霍夫曼编码函数。

首先,我们需要了解霍夫曼编码的基本原理。

该算法基于字符出现的频率构建一个霍夫曼树,其中出现频率较高的字符位于树的较低层,而出现频率较低的字符位于树的较高层。

然后,通过从根节点到每个字符的路径上的比特串表示字符的编码。

这样,频率较高的字符将使用较短的比特串编码,而频率较低的字符将使用较长的比特串编码。

在Matlab中实现霍夫曼编码,我们首先需要计算每个字符在给定数据中的出现频率。

我们可以使用Matlab提供的`histcounts`函数来实现这一点。

`histcounts`函数将数据分成一定数量的称为“bins”的区间,并计算每个区间中的数据的频数。

matlabdata = 'abcdefgh'; 给定的数据frequencies = histcounts(data, unique(data)); 计算每个字符的频数上述代码首先定义了一个包含字符的字符串,然后使用`unique`函数获取字符串中的唯一字符。

然后,`histcounts`函数基于这些唯一字符计算每个字符的频数,并将结果存储在名为“frequencies”的数组中。

下一步是构建霍夫曼树。

我们可以使用以下步骤来实现此操作:1. 创建一个含有所有字符频数的结点集合,并按照频率从低到高对结点排序。

2. 从频率最低的两个结点中创建一个新的父节点,并将这个父节点的频率设置为这两个结点的频率之和。

将这个新的父节点添加到结点集合中,并删除这两个被合并的结点。

3. 重复步骤2,直到只剩下一个节点为止。

这个节点将成为霍夫曼树的根节点。

霍夫曼编码的MATLAB实现

霍夫曼编码的MATLAB实现

霍夫曼编码的MATLAB实现%哈夫曼编码的MATLAB实现(基于0、1编码):clc;clear;A=[0.3,0.2,0.1,0.2,0.2];信源消息的概率序列A=fliplr(sort(A));%按降序排列T=A;[m,n]=size(A);B=zeros(n,n-1);%空的编码表(矩阵)for i=1:nB(i,1)=T(i);%生成编码表的第一列endr=B(i,1)+B(i-1,1);%最后两个元素相加T(n-1)=r;T(n)=0;T=fliplr(sort(T));t=n-1;for j=2:n-1%生成编码表的其他各列for i=1:tB(i,j)=T(i);endK=find(T==r);B(n,j)=K(end);%从第二列开始,每列的最后一个元素记录特征元素在%该列的位置r=(B(t-1,j)+B(t,j));%最后两个元素相加T(t-1)=r;T(t)=0;T=fliplr(sort(T));endB;%输出编码表END1=sym('[0,1]');%给最后一列的元素编码END=END1;t=3;d=1;for j=n-2:-1:1%从倒数第二列开始依次对各列元素编码for i=1:t-2if i>1 & B(i,j)==B(i-1,j)d=d+1;elsed=1;endB(B(n,j+1),j+1)=-1;temp=B(:,j+1);x=find(temp==B(i,j));END(i)=END1(x(d));endy=B(n,j+1);END(t-1)=[char(END1(y)),'0'];END(t)=[char(END1(y)),'1'];t=t+1;END1=END;endA%排序后的原概率序列END%编码结果for i=1:n[a,b]=size(char(END(i)));endavlen=sum(L.*A)%平均码长H1=log2(A);H=-A*(H1')%熵P=H/avlen%编码效率提取这一列两个最小值相加在后一列中的位置以及其编码。

哈夫曼编码算法实现完整版

哈夫曼编码算法实现完整版

哈夫曼编码算法实现完整版下面是哈夫曼编码算法的完整实现。

1.统计字符频率首先,我们需要统计待压缩的文本中每个字符出现的频率。

遍历文本文件,统计每个字符的出现次数。

将字符和对应的频率存储在一个频率表中。

2.构建哈夫曼树接下来,我们使用统计得到的频率表构建哈夫曼树。

哈夫曼树是一种二叉树,每个内部节点都有两个子节点,分别代表0和1首先,将频率表中的每个字符作为叶子节点,并按照频率从小到大进行排序。

然后,依次选择频率最小的两个节点,将它们作为子节点创建一个新的节点,并将新节点的频率设置为这两个节点频率之和。

将新节点插入到频率表中,然后删除原来的两个节点。

重复上述步骤,直到频率表中只剩下一个节点,即哈夫曼树的根节点。

3.生成编码表根据构建好的哈夫曼树,我们可以生成字符的编码表。

遍历哈夫曼树,记录从根节点到每个叶子节点的路径,其中0代表左子节点,1代表右子节点。

4.压缩数据通过编码表,我们可以将原始数据进行压缩。

遍历原始文本,将每个字符替换为对应的编码,然后将所有编码拼接成一个二进制字符串。

5.存储压缩后的数据将压缩后的二进制字符串进行存储,可以使用二进制文件或者文本文件存储。

6.解压数据对于解压,我们需要加载压缩后的数据,并重新构建哈夫曼树。

遍历压缩后的二进制字符串,根据哈夫曼树的结构逐个读取二进制位,当遇到叶子节点时,输出对应的字符。

通过上述步骤,我们可以实现对文本数据的压缩和解压。

需要注意的是,由于哈夫曼编码是基于字符频率进行优化的,所以对于不同的文本文件,编码效果也会有所不同。

较为重复的字符出现频率高的文本文件,哈夫曼编码效果会更好。

哈夫曼编码matlab

哈夫曼编码matlab

哈夫曼编码matlab1. 引言哈夫曼编码是一种广泛应用于数据压缩领域的编码算法,它通过使用变长编码来表示不同符号,使得出现频率高的符号使用较短的编码,而出现频率低的符号使用较长的编码。

这种编码方式可以有效地降低数据的存储空间,提高数据传输效率。

在本文中,我们将使用Matlab编程语言来实现哈夫曼编码算法,并介绍其原理和实现步骤。

2. 哈夫曼编码原理哈夫曼编码的核心思想是根据符号的出现频率来构建一棵哈夫曼树,树中的叶子节点对应着不同的符号,而每个符号的编码则通过从根节点到达对应叶子节点的路径来表示。

构建哈夫曼树的过程可以分为以下几个步骤:2.1 统计符号频率首先,我们需要统计待编码数据中各个符号的出现频率。

在Matlab中,我们可以使用histc函数来实现这一步骤。

2.2 构建哈夫曼树根据频率统计结果,我们可以构建一棵哈夫曼树。

构建哈夫曼树的过程可以简化为以下几个步骤: 1. 将每个符号作为一个单独的节点插入到一个优先队列中。

2. 从优先队列中选择两个频率最低的节点,并合并它们为一个新节点。

该新节点的频率为两个被合并节点的频率之和。

3. 将新节点插入到优先队列中。

4. 重复步骤2和3,直到优先队列中只剩下一个节点为止。

该节点即为哈夫曼树的根节点。

2.3 生成编码表在构建好的哈夫曼树上,每个叶子节点都对应着一个符号,编码就是从根节点到达叶子节点的路径。

我们可以通过遍历哈夫曼树来生成每个符号的编码。

从根节点出发,如果经过左子树则编码为0,经过右子树则编码为1。

遍历到叶子节点时,记录下从根节点到达该叶子节点的路径,即为该符号的编码。

3. 哈夫曼编码的实现接下来,我们将使用Matlab来实现哈夫曼编码算法。

首先,我们需要读取待编码的数据。

3.1 读取数据使用Matlab提供的文件读取函数,我们可以方便地读取文本文件或二进制文件。

在本例中,我们以文本文件为例,假设我们需要对一段文本进行编码。

下面是读取文本文件的示例代码:fid = fopen('input.txt', 'r');textData = fscanf(fid, '%c');fclose(fid);3.2 统计符号频率读取数据后,我们需要统计各个符号的频率。

matlab哈夫曼编码

matlab哈夫曼编码

matlab哈夫曼编码哈夫曼编码是一种常见的数据压缩算法,可以将数据压缩至原始数据的一小部分,从而减少存储空间和传输时间。

Matlab提供了内置函数来实现哈夫曼编码。

1. 哈夫曼树的构建在Matlab中,可以使用huffmandict函数来构建哈夫曼树。

该函数接受一个包含符号和它们对应权重的向量作为输入,并返回一个包含每个符号对应编码的字典。

例如,要将字符串"hello world"进行编码,可以使用以下代码:```s = 'hello world';symbols = unique(s);freq = hist(s,symbols);dict = huffmandict(symbols,freq);```其中,unique函数用于获取字符串中唯一的符号集合,hist函数用于计算每个符号出现的频率。

huffmandict函数则用于构建哈夫曼树并生成字典。

2. 数据压缩有了哈夫曼字典后,就可以将原始数据进行压缩。

在Matlab中,可以使用huffmanenco函数来进行数据压缩。

该函数接受一个包含原始数据的向量和之前生成的哈夫曼字典作为输入,并返回一个包含压缩后二进制数据的向量。

例如,在上面例子中生成的字典下,可以将字符串"hello world"进行压缩:```encoded = huffmanenco(s,dict);```3. 数据解压对于压缩后的数据,可以使用huffmandeco函数进行解压。

该函数接受一个包含压缩后二进制数据的向量和之前生成的哈夫曼字典作为输入,并返回一个包含解压后原始数据的向量。

例如,在上面例子中生成的字典下,可以将上一步得到的压缩数据进行解压:```decoded = huffmandeco(encoded,dict);```4. 完整代码综合以上步骤,可以得到完整的Matlab代码:```s = 'hello world';symbols = unique(s);freq = hist(s,symbols);dict = huffmandict(symbols,freq);encoded = huffmanenco(s,dict);decoded = huffmandeco(encoded,dict);```其中,s是待编码字符串,symbols是符号集合,freq是每个符号出现频率。

哈夫曼编码

哈夫曼编码

图像编码与压缩——哈夫曼编码专业班级:10 信息安全学生姓名:王猛涛学生学号:_ 20101616310049 _指导教师:姚孝明完成时间:2013年4月13日_数字图像处理实验六:图像编码与压缩——哈夫曼编码一、实验目的1. 了解图像的哈夫曼编码原理。

2. 掌握哈夫曼编码算法。

二、实验主要仪器及设备1. 微型计算机:Intel Pentium及更高。

2. MATLAB软件(含图像处理工具箱)。

三、实验原理(Huffman编码)1. 可变码长最佳编码定理定理:在变长编码中,如果码字长度严格按照信号中符号出现概率大小的相反顺序排列,则平均码字长度一定小于其他符号顺序排列方式的平均码字长度。

D.A.Huffman(哈夫曼)在1952年根据可变长最佳编码定理,提出了依据信源集中符号出现的概率分配不同长度的唯一可译码的算法。

接收端在得到哈夫曼编码后,通过解码可以得到与输入完全一致的信号。

2.前缀码(prefix code)一组唯一可译码中的任意一个码字都只与一种信号存在对应关系。

为了译码的需要,在唯一可译码中的前缀码保证任意一个码字都不是其他码字的前缀。

例如,有一维图像的符号集合为{EMBED Equation.KSEE3 \* MERGEFORMAT |)}fffi)(ff ,设定的码字集合。

编码系统解码时,只要一遇到),3(4({),2(),1(“0”,便知道对应的是。

若接收到的是“1”,则等待下一个比特,若下一个比特为“0”。

即确定是,若下一个比特是“1”,则等待第三个比特。

若第三个比特为“0”,则可判定信号为,否则为。

若一前缀码为010*******,则译码的输出信号序列为。

可见前缀码保证了这样译出的码字具有唯一性和“即时性”。

3.Huffman编码Huffman编码的算法如下:(1)将图像的灰度等级按概率大小进行升序排序。

(2)在灰度级集合中取两个最小概率相加,合成一个概率。

(3)新合成的概率与其他的概率成员组成新的概率集合。

基于matlab对哈夫曼编码的实现

基于matlab对哈夫曼编码的实现

在MATLAB中实现哈夫曼编码需要先建立哈夫曼树,然后基于这颗哈夫曼树生成对应的哈夫曼编码。

以下是使用MATLAB实现哈夫曼编码的简单步骤:
假设你有一个要编码的符号集合symSet和这些符号的概率集合probSet。

1.计算频率和概率: 首先,我们需要计算每个符号的频率和概率。

freq = histc(symSet, symSet); % 计算频率
prob = freq / sum(freq); % 计算概率
2.构建哈夫曼树: 使用huffTree函数构建哈夫曼树。

[huffTree, huffCodes] = huffTree(prob);
3.生成哈夫曼编码: 使用huffmanenco函数生成哈夫曼编码。

huffmanCodes = huffmanenco(symSet, huffTree);
4.测试: 使用生成的哈夫曼编码对原始数据进行编码和解码。

originalData = symSet(randperm(length(symSet), 1000)); % 随机生成1000个原始数据
encodedData = huffmanenco(originalData, huffTree); % 对原始数据进行编码
decodedData = huffDeco(encodedData, huffCodes); % 解码编码后的数据
5.比较解码后的数据与原始数据: 检查解码后的数据是否与原始数据匹配。

以上是MATLAB实现哈夫曼编码的基本步骤,具体的代码可能需要根据你的数据和需要进行一些调整。

实验1 Huffman编码生成器-matlab

实验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)为信息熵函数%

matlab 哈夫曼编码

matlab 哈夫曼编码

matlab 哈夫曼编码哈夫曼编码是一种可变长度的编码方式,它可以将一组可能不等概率出现的字符序列压缩成一个二进制编码的表示方式,以达到数据压缩的目的。

在哈夫曼编码中,出现频率越高的字符所对应的编码越短,反之越长。

需要注意的是,将字符压缩成的二进制编码只能满足单词不重复的情况下才能唯一的解码出来,因此在实际应用中还需要对编码进行强制分界,以保证无二义性。

在Matlab中进行哈夫曼编码可以使用built-in函数'huffmandict'和'huffmanenco'来完成。

其中'huffmandict'函数根据字符和频率信息来生成哈夫曼字典,'huffmanenco'函数将读入的原始数据运用哈夫曼编码压缩成一个码字,也可以使用'huffmandeco'函数将压缩后的数据解码。

下面我给出一个简单的演示,解释如何使用Matlab实现哈夫曼编码过程。

假设我们要压缩的原始数据如下:matlabcharList = ['a', 'b', 'c', 'd', 'e', 'f'];probList = [0.2, 0.15, 0.1, 0.12, 0.3, 0.13];data = ['a', 'c', 'b', 'a', 'e', 'b', 'f', 'e', 'f', 'c', 'c', 'a', 'd', 'a', 'b', 'e'];首先我们需要生成一个哈夫曼字典:matlabhuffDictionary = huffmandict(charList, probList);这里的'huffmandict'函数通过输入字符符号和对应概率的向量,生成一个哈夫曼字典。

matlab信源二进制赫夫曼编码

matlab信源二进制赫夫曼编码

信源二进制赫夫曼编码是一种常见的数据压缩算法,它可以有效地降低数据传输和存储的成本。

在本文中,我将深入探讨matlab中的信源二进制赫夫曼编码的原理、实现和应用,并共享我的个人观点和理解。

让我们来了解一下信源编码的基本概念。

信源编码是一种将离散或连续信号转换为离散符号的过程,其目的是尽量减少信号的冗余度,以便更高效地传输和存储。

在数字通信和数据存储领域,信源编码起着至关重要的作用。

而二进制赫夫曼编码是一种常见的无损数据压缩算法,其核心思想是通过对出现频率较高的符号赋予较短的编码,而对出现频率较低的符号赋予较长的编码,从而实现数据的压缩。

在matlab中,我们可以利用赫夫曼树和编码表来实现信源二进制赫夫曼编码。

接下来,我将详细介绍matlab中的信源二进制赫夫曼编码的实现过程。

在matlab中,我们可以使用`huffmandict`函数来创建赫夫曼编码字典,该函数需要输入符号和它们对应的概率作为参数。

我们可以使用`huffmanenco`函数来对输入的符号序列进行赫夫曼编码,得到压缩后的二进制码字。

我们可以使用`huffmandeco`函数来对压缩后的二进制码字进行解码,得到原始的符号序列。

通过这些函数的组合,我们可以在matlab中轻松实现信源二进制赫夫曼编码。

具体的实现细节和示例代码我将在下文中进行详细讲解。

信源二进制赫夫曼编码的应用非常广泛,特别是在无线通信、图像压缩和音频处理等领域。

通过使用赫夫曼编码,我们可以大大减小数据传输和存储的成本,提高系统的效率和可靠性。

赫夫曼编码也是信息论中的重要概念,它为我们理解信息压缩和编码提供了重要的思路和方法。

从个人观点来看,信源二进制赫夫曼编码作为一种经典的数据压缩算法,具有重要的理论意义和实际应用价值。

在matlab中,我们可以利用现成的函数库来实现赫夫曼编码,同时也可以根据具体的应用场景进行定制化的优化。

通过不断深入研究和实践,我们可以进一步发掘赫夫曼编码的潜力,为数据压缩和信息传输领域带来更多的创新和突破。

Huffman编码(哈夫曼编码)的Matlab实现

Huffman编码(哈夫曼编码)的Matlab实现

clear 【1 】all fprintf('Reading data...')data=imread('cameraman.tif');data=uint8(data);%读入数据,并将数据限制为uint8 fprintf('Done!\n')%编码紧缩fprintf('compressing data...');[zipped,info]=norm2huff(data);fprintf('Done!\n')%解紧缩fprintf('compressing data...');unzipped=huff2norm(zipped,info);fprintf('Done!\n')%测试是否无掉真isOK=isequal(data(:),unzipped(:))%显示紧缩后果whos datazippedunzippedfunction [zipped,info]=norm2huff(vector)if~isa(vector,'uint8'),error('input argument must be a uint8 vector') endvector=vector(:)';%将输入向量转换为行向量f=frequency(vector);%盘算个元素消失的概率simbols=find(f~=0);f=f(simbols);%将元素按消失的概率分列[f,sortindex]=sot(f);simbols=simbols(sortindex);%产生码字 generate the codeword as the 52 bits of a doublelen=length(simbols);simbols_index=num2cell(1:len);codeword_tmp=cell(len,1);while length(f)>1,index1=simbols_index{1};index2=simbols_index{2};codeword_tmp(index1)=addnode(codeword_tmp(index1),uint8(0)); codeword_tmp(index2)=addnode(codeword_tmp(index2),uint8(1)); f=[sum(f(1:2)) f(3:end)];simbols_index=[{[index1 index2]} simbols_index(3:end)];%将数据从新分列,是两个节点的频率尽量与前一个节点的频率想当resort datainordertohavetwonodeswithlowerfrequencyasfirst to[f,sortindex]=sort(f);simbols_index=simbols_index(sortindex);end%对应响应的元素与码字codeword=cell(256:1);codeword(simbols)=codeword_tmp;%盘算总的字符串长度len=0;for index=1:length(vector),len=len+length(codeword{double(vector(index))+1}); end%产生01序列string=repmat(uint8(0),1,len);pointer=1;for index=1:length(vector),code=codeword{double(vector(index))+1};len=length(code);string(pointer+(0:len-1))=code;pointer=pointer+len;end%假如须要,加零len=length(string);pad=8-mod(len,8);if pad>0,string=[string uint8(zeros(1,pad))];end%保管现实有效的码字codeword=codeword(simbols);codelen=zeros(size(codeword));weights=2.^(0:23);maxcodelen=0;for index 1:length(codeword),len=length(codeword{index});if len>maxcodelen,maxcodelen=len;endif len>0,code=sum(weights(codeword{index}==1)); code=bitset(code,len+1);codeword{index}=code;codelen(index)=len;endendcodeword=[codeword{:}]%盘算紧缩后的向量cols=length(string)/8;string=reshape(string,8,cols);weights=2.^(0:7);zipped=uint8(weights*double(string));%存储一个稀少矩阵huffcodes=sparse(1,1);% init sparse matrixfor index=1:numel(codeword),huffcodes(codeword(index),1)=simbols(index); end%产生信息构造体info.pad=pad;info.ratio=cols./length(vector);info.length=length(vector);info.maxcodelen=maxcodelen;function codeword_new=addnode(codeword_old,item)codeword_new=cell(size(codeword_old));for index=1:length(codeword_old),codeword_new{index}=[item codeword_old{index}];endfunction vector=huff2norm(zipped,info)%HUFF2NORM Huffman 解码器%HUFF2NORM(X,INFO)依据信息体构造 info 返回向量 zipped 的解码成果%%矩阵参数以X(:)情势输入if~isa(zipped,'uint8'),error('input argument must be a uint8 vector')end%产生01序列len=length(zipped);string=repmat(uint8(0),1,len.*8);bitindex=1:8;for index+1:len,string(bitindex+8.*(index-1))=uint8(bitget(zipped(index),bitindex)); end%调剂字符串string=logical(string(:)');% remove 0 paddinglen=length(string);%解码weights=2.^(0:51);vector=repmat(uint8(0),1,info,length);vectorindex=1;codeindex=1;code=0;for index=1:len,code=bitset(code,codeindex,string(index));]codeindex=codeindex+1;byte=decode(bitset(code,codeindex),info);if byte>0,%vector(vectorindex)=byte-1;codeindex=1;code=0;vectorindex=vectorindex+1;endendfunction byte=decode(code,info)byte=info.huffcodes(code);function f=frequency(vector)%FREQUENCY 盘算元素消失概率if~isa(vector,'uint8'),error('input argument must be a uint8 vector') endf=repmat(0,1,256);%扫描向量len=length(vector);for index=0:256,%f(index+1)=sum(vector==uint8(index)); end%归一化f=f./len;。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

编写Matlab函数实现哈夫曼编码的算法一、设计目的和意义在当今信息化时代,数字信号充斥着各个角落。

在数字信号的处理和传输中,信源编码是首先遇到的问题,一个信源编码的好坏优劣直接影响到了后面的处理和传输。

如何无失真地编码,如何使编码的效率最高,成为了大家研究的对象。

哈夫曼编码就是其中的一种,哈夫曼编码是一种变长的编码方案。

它由最优二叉树既哈夫曼树得到编码,码元内容为到根结点的路径中与父结点的左右子树的标识。

所以哈夫曼在编码在数字通信中有着重要的意义。

可以根据信源符号的使用概率的高低来确定码元的长度。

既实现了信源的无失真地编码,又使得编码的效率最高。

二、设计原理哈夫曼编码(Huffman Coding)是一种编码方式,哈夫曼编码是可变字长编码(VLC)的一种。

uffman于1952年提出一种编码方法,该方法完全依据字符出现概率来构造异字头的平均长度最短的码字,有时称之为最佳编码,一般就叫作Huffman编码。

而哈夫曼编码的第一步工作就是构造哈夫曼树。

哈夫曼二叉树的构造方法原则如下,假设有n个权值,则构造出的哈夫曼树有n个叶子结点。

n 个权值分别设为w1、w2、…、wn,则哈夫曼树的构造规则为:(1) 将w1、w2、…,wn看成是有n 棵树的森林(每棵树仅有一个结点);(2) 在森林中选出两个根结点的权值最小的树合并,作为一棵新树的左、右子树,且新树的根结点权值为其左、右子树根结点权值之和;(3)从森林中删除选取的两棵树,并将新树加入森林;(4)重复(2)、(3)步,直到森林中只剩一棵树为止,该树即为所求得的哈夫曼树。

具体过程如下图1产所示:(例)图1 哈夫曼树构建过程哈夫曼树构造成功后,就可以根据哈夫曼树对信源符号进行哈夫曼编码。

具体过程为先找到要编码符号在哈夫曼树中的位置,然后求该叶子节点到根节点的路径,其中节点的左孩子路径标识为0,右孩子路径标识为1,最后的表示路径的01编码既为该符号的哈夫曼编码。

可以知道,一个符号在哈夫曼树中的不同位置就有不同的编码。

而且,不同符号的编码长度也可能不一样,它由该结点到父结点的路径长度决定,路径越长编码也就越长,这正是哈夫曼编码的优势和特点所在。

它以各符号出现的概率大小将各符号的编码区分开。

例如对上例图中“1”的编码为“100”,“3”的编码为“101”,“5”的编码为“11”。

对于一个信源消息的熵可以以下公式(1)求得:(1)其中H(x)表示信源的总信息量,既为信源的熵。

p()为信源中一特定符号出现的概率。

三、详细设计步骤1) 首先对设计题目进行系统理论分析。

由给定的8种可能符号的信源,各种符号发生的概率分别为:0.30、0.16、0.14、0.12、0.10、0.09、0.06、0.04。

可以根据哈夫曼树的构造原理得出如下哈夫曼树型结构(图2):图2 哈夫曼树其中每个结点中的上面的整数为结点有编号,下面的小数为该结点的权值,在这里指的各结点的概率。

2) 由以是的哈夫曼树图,根据哈夫曼的编码规则可求该8个输出符号的顺序为:0.30,0.16,0.14,0.12,0.10,0.09,0.06,0.04对应编码输出应该为:1 0 1 1 0 1 1 1 0 1 0 0 0 0 0 0 1 0 1 1 0 0 1 1 1,编码长度为25。

3)由熵的计算公式可知:H(X)=-(0.30.3+0.160.16+0.140.14+0.0.12+0.10.1+0.090.09+0.060.06+0.040.04)=2.78244)哈夫曼树在matlab中的构造,在matlab中用tree(MN,s1,s2,s3……)这个系统函数来构造哈夫曼二叉树。

声明一个tree(5,x)结构的树型结点,一个结点包括有5个变量存储单元。

其中tree(1,x)记录该结点的编号;tree(2,x)记录该结点的概率值;tree(3,x)记录该结点的父结点编号;tree(4,x)记录该结点是左结点还是右结点(其中左结点为“0”,右结点为“1”);tree(5,x)记录该结点是否为根结点标志(该结点为根结点记为“1”,否则决为“0”)。

由哈夫曼树构造原则,先选出所有结点中概率值最小的两个结点,把这两个结点组合在一起形成一个新的二叉树。

新二叉树的根结点为两个子结点的概率这和,同时根据实际情况标记结点的相关属性(如左右子结点,是否为根结点),之后再将新的二叉树跟剩下的结点集合在一起,再选出概率值最小的两个结点,并重复以上的过程,直到把所有的结点都加到二叉树中,开成一根哈夫曼二叉树。

在matlab编程实现中先编写一个子函数用于找出所有结点中概率值最小的两个结点,子函数如下:function [l,r]=findminval(tree)s=find(tree(5,:)==1);if size(s,2)<2error('Error input!');endfirval=realmax;secval=realmax;for i=s;if firval>tree(2,i)if secval>firvalsecond=first;secval=firval;endfirst=i;firval=tree(2,i);elseif secval>tree(2,i)second=i;secval=tree(2,i);endendl=min([first,second]);r=max([first,second]);5)然后再编写代码实现哈夫曼树的构建,通过循环调用tree()函数,并加以判断完成哈夫曼树的构造,代码如下:%哈夫曼树结点数据结构%pro为一概率向量%tree(1,*)结点序号%tree(2,*)概率%tree(3,*)父结点序号%tree(4,*)左右标志%tree(5,*)结点是否是根结点标志%生成的哈夫曼树n=size(pro,2);%得到字符个数tree=ones(5,2*n-1);%构造树数据结构tree(1,:)=1:(2*n-1);%填充结点序号tree(5,(n+1):end)=0;%设置结点是否在集合tree(2,1:n)=pro;%设置概率for i=(n+1):(2*n-1);%循环控制[l,r]=findminval(tree);%找到集合中两个最小的值的序号tree(2,i)=tree(2,l)+tree(2,r);%得到父结点概率值tree(5,i)=1;%设置新构造结点在集合中tree(3,l)=i;tree(3,r)=i;%设置父结点序号tree(4,l)=0;tree(4,r)=1;%设置左右标志tree(5,l)=0;tree(5,r)=0;%设置不在集合中endHuffmanTree=tree;6)调用循环计算信源的熵,代码如下:Entropy=0;%初始化为0for j=1:n;%循环累加求信源的熵Entropy=Entropy-pro(j)*log2(pro(j));end7)由哈夫曼树生成哈夫曼编码,既哈夫曼树的遍历,同时统计编码的长度,此处采用由下往上的遍历方式,获得路径编码后再将编码倒一次序,得到的编码既为信源称号的哈夫曼编码,最后再将所有符号的编码组合在一起,代码如下:%由下至上完成哈夫曼编码HuffmanCode=[];%初始化定义Code=[];SumCode=0;LastPoint=1;int z;for k=1:n;%循环完成n个符号的编码CodeNumber=1;m=k;while(tree(5,m)~=1)%判断是否已遍历到根结点if tree(4,m)==0%判断为左结点编码为0Code(CodeNumber)=0;CodeNumber=CodeNumber+1;elseif tree(4,m)==1%判断为右结点编码为1Code(CodeNumber)=1;CodeNumber=CodeNumber+1;endm=tree(3,m);%指向父结点endCodeNumber=CodeNumber-1;SumCode=SumCode+CodeNumber;%累加计算编码长度for z=LastPoint:SumCode;%将n个符号的编码组合到一起HuffmanCode(z)=Code(CodeNumber);CodeNumber=CodeNumber-1;z=z+1;endLastPoint=z;end8)最后将以上的代码整合到一个子函数中,并设置函数的传入参数为信源符号的概率向量,同时使函数返回哈夫曼树,哈夫曼编码,编码长度以及信源的熵,函数头如下:function [HuffmanTree,HuffmanCode,SumCode,Entropy] = Huffman(pro)四、设计结果及分析完成编写设计后,在matlab中运行并验证结果,首先输入概率向量:>> pro=[0.30,0.16,0.14,0.12,0.10,0.09,0.06,0.04];再调用编写的Huffman函数:>> [HuffmanTree,HuffmanCode,SumCode,Entropy] = Huffman(pro)回车即可得到执行的结果:(见附图3)所得的结果与实际预测的理论结果一致无误。

五、体会通过本次数字通信课程的设计,深刻体会了数字编码的全过程。

认识到了无失真和高效率编码在数字通信中的重要性。

清楚了哈夫曼编码的整体过程和细节,首先构建哈夫曼二叉树,再通过该二叉树遍历得到哈夫曼编码值。

对二叉树的构建过程的判断方式和构建原则有了更深的认识。

同时,进一步使用了matlab 这个软件工具,进一步熟悉了在matlab中的编程的语法和结构。

认识到了软件工具在通信科研仿真方面的重要作用和方便性。

同时在专业方面丰富了知识面,增长了见闻。

了解到了更多的通信方面的专业名词和术语。

对以后的更深入的学习的工作打下了基础。

相关文档
最新文档