Huffman编码与译码 代码

Huffman编码与译码 代码
Huffman编码与译码 代码

% 1 完成对输入的序列进行各个码元的概率统计;

%完成对字符串中的各字符的统计,并列出其概率分布矩阵,返回pro矩阵

%s:待编码序列,S:所含的码元序列

function pro=getpro(s)

pro=[];

a=length(s);

S=unique(s);

b=length(S);

c=zeros(1,b); %用以存放个序列中各个码元的个数;

%/////////////////////////////////////////////

%进行概率计算;

for i=1:b

for j=1:a

if S(i)==s(j)

c(i)=c(i)+1;

else continue;

end;

end;

end;

pro=c./a;

disp(S);

disp(pro);

%完成对已知编码序列的译码,以及在改变码表中的某一位值得情况下,再一次译码,计算其误码率;

%Codenumber:已编码序列;huffmantable:码表;Code2:各码元的码长;pro2:各码元的概率分布矩阵;

%s:原始序列;decodenumber:译码序列;

function decodenumber=huffmandecode(Codenumber,huffmantable,Code2,pro2,bit)

mm=unique(bit); %码元序列

mm=mm(pro2(2,:));

[lx,ly]=size(huffmantable);

LL=size(Codenumber,2);

decodenumber=[];

ZF=[Codenumber,-ones(1,max(Code2))];

for j=1:length(bit)

for i=1:lx

k=Code2(i);

while(ZF(1:k)==huffmantable(i,1:k))

decodenumber=[decodenumber,mm(i)];

ZF=ZF(k+1:end);

end

end

end

disp('译码序列如下:');

disp(decodenumber);

disp('原始序列如下:');

disp(bit);

end %对于译码部分所用到的部分主要是编码时生成的码表以及huffmantree,在进行编码的时候,

%通过筛选后的源字符串的字符序列的下标,与码表中的每行相对应的原则,遍历编码序列;

%在遍历的时候,通过码表中各行的码长,控制遍历的长度,与每行中的码表进行比较,输出相对应的字符,即完成了译码。

% 3 编码,完成构成完整的基本树,形成huffmantree,并对其遍历,得到码表,通过码表对序列进行编码,并求其平均码长,信息熵,编码效率;

% HuffmanTree 哈夫曼树,pro 码元概率分布矩阵,S,待编码序列;

function [Codenumber,huffmantable,Code2]=huffmanencode(HuffmanTree,pro,bit)

p=pro;

a1=unique(bit);

a2=bit;

len1=length(a1); %码元序列的长度;

len2=length(a2); %所要编码序列的长度;

a3=zeros(1,len2); %生成与编码序列长度一样的零矩阵,用以存放编码对应的下标;

Code=[]; %存放其遍历一个码元所对应的编码;

Code2=[]; %记录各个码元的码长;

Lastnumber=1;

Sumnumber=0; %累积计算编码总长度;

huffmantable=-ones(len1,len1); %建立len1*len1的单位负矩阵,用以存放其码表;

%遍历二叉树,生成码表huffmantable;

for i=1:len1; %循环完成len1个符号的编码;

k=pro(2,i);

key=1;

m=find(HuffmanTree(6,1:len1)==k);

while(HuffmanTree(5,m)~=1) %判断是否遍历到根结点;

Code(key)=HuffmanTree(4,m);

key=key+1;

m=HuffmanTree(3,m); %指向父节点;

end

lc=length(Code);

huffmantable(i,1:lc)=fliplr(Code); %将Code矩阵中的编码左右翻转,完成倒序排列;

Code2=[Code2,lc]; %将各个码元的编码长度赋予矩阵Code2;

end

%显示码表,即只输出矩阵huffmantable中非-1的部分;

disp('码表如下:');

Code4=[];

for i=1:len1 %显示其码表;

disp(a1(pro(2,i)));

flag=1;

while(huffmantable(i,flag)~=-1)

Code4(flag)=huffmantable(i,flag);

flag=flag+1;

end;

Code4,disp('码长='),Code2(i)

end;

%通过以上生成的码表,然后遍历源字符串与unique之后的字符串,找出其下标并对应输出码表中对应的编码序列,

%这样源字符串的编码就完成了,以下是编码部分的主要代码:

%%通过码元与待编码的序列一一比较,输出huffmantable中对应的编码;

Codenumber=[];

for i=1:len2

for j=1:len1

if a1(j)==a2(i)

v=find(HuffmanTree(6,:)==j);

flag=1;

while(huffmantable(v,flag)~=-1)

Code1(flag)=huffmantable(v,flag);

flag=flag+1;

Sumnumber=Sumnumber+1;

end;

Codenumber(Sumnumber-flag+2:Sumnumber)=[Code1(1:flag-1)];

end;

end;

end;

disp('编码如下:');

disp(Codenumber);

%计算其平均码长;

PJ_Code=pro(1,:)*Code2';

%计算其信息熵;

HX=0;

for i=1:len1

HX=HX-pro(1,i)*log2(pro(1,i));

end;

%计算其编码效率;

N=HX/PJ_Code;

disp('平均码长:');

PJ_Code

disp('信息熵:');

HX

disp('编码效率:');

N

end

function []=huffmanmain()

disp('请输入待编码序列');

s=input('','s'); %调用概率统计函数,输出各码元的概率分布矩阵;

pro=getpro(s); %调用生成huffmantree函数,输出基本树,及完整huffmantree;[HuffmanTree,pro2]=huffmantree(pro); %调用编码函数,输出码表,编码序列,平均码长,信息熵,编码效率;

[Codenumber,huffmantable,Code2]=huffmanencode(HuffmanTree,pro2,s); %调用译码函数,输出译码序列以及误码率;

decodenumber=huffmandecode(Codenumber,huffmantable,Code2,pro2,s);

%改变编码序列中的前两个值,即是0的变为1,是1的变为0,然后再进行重新译码输出

Codenumber1=yiweicodenumber(Codenumber); %调用译码函数,对错位后的编码序列进行译码

decodenumber=huffmandecode(Codenumber1,huffmantable,Code2,pro2,s);

% 2 通过构建二叉树,遍历huffman树,从而得到其对应的码表;

%pro1:各码元概率分布矩阵,pro2: 各码元按倒序排列后的顺序以及对应之前的位置;function [HuffmanTree,pro2]=huffmantree(pro1)

%构建基础二叉树

LL=length(pro1);

[p1,p2]=sort(pro1,'descend');

pro2=zeros(2,LL);

pro2(1,:)=p1;

pro2(2,:)=p2;

n0=size(pro2,2);

n1=ceil(log2(n0)); %二叉树的深度;

n=LL;

tree=ones(6,2*n-1); %构造二叉树。声明一个tree(6,x)结构的树型结点,一个结点包括有6 个变量存储单元。

%建立其6*2*n-1的单位1矩阵,用以存储二叉树中各个结点,父节点,以及各个结点的编号;

tree(1,:)=1:(2*n-1); %用以编号并存储二叉树中的结点;

tree(5,(n+1):end)=0; %用以存放其根结点;标记为1时作为结束标志

tree(2,1:n)=pro2(1,:); %用以存放概率分布;

tree(6,1:n)=pro2(2,:); %用以存放每个概率对应的符号的下标;

tree(6,n+1:end)=0;

disp('基本树形式:'); %显示构建其的基本树形式;

disp(tree); % tree(1,x)记录该结点的编号;tree(2,x)记录该结点的概率值;tree(3,x)记录该结点的父结点编号;

%tree(4,x)记录该结点是左结点还是右结点(其中左结点为“0”,右结点为“1”);

%tree(5,x)记录该结点是否为根结点标志(该结点为根结点记为“1”,否则决为“0”);

%tree(6,x)记录该结点的字符,x 为pro 中源字符经过筛选后的下标数,其余值赋为零。

%对概率分布矩阵进行运算,每次进行最小两个值相加,其和赋予其中一个,另外一个置1,重复操作,

%将其每一次输出的结果存于s1矩阵中,至最后两个概率和为1结束;

s1=ones(n-1,2*n-1);

s1(1,:)=sort(tree(2,:));

for i=2:n

s1(i,:)=[s1(i-1,1)+s1(i-1,2),1,s1(i-1,3:2*n-1)];

s1(i,:)=sort(s1(i,:));

end;

%对基础二叉树进行操作,完整构造;

m1=0;m2=0;

s2=tree(2,:); %将tree(2,:)中的概率分布赋予s2矩阵中,在不改变tree(2,:)中概率分布,方便对其操作;

for i=(n+1):(2*n-1);

min1=find(s2==s1(i-n,1)); %从tree(2,:)中找对应于s1矩阵中每一行的最小的两个概率值的下标;

%为避免tree(2,:)中出现两个相同的最小值,将进行如下判断并操作;

if length(min1)==1

m1=min1;

min2=find(tree(2,:)==s1(i-n,2));

m2=min2(1);

else

m1=min1(1,1);

m2=min1(1,2);

end;

%///////////////////////////////////////////////////////

tree(2,i)=tree(2,m1)+tree(2,m2);

s2(i)=tree(2,m1)+tree(2,m2);

s2(m1)=-1;

s2(m2)=-1;

tree(5,i)=1;

tree(3,m1)=i;tree(3,m2)=i;

tree(4,m1)=1;tree(4,m2)=0;

tree(5,m1)=0;

tree(5,m2)=0;

end

HuffmanTree=tree;

disp('哈夫曼树如下:');

disp(HuffmanTree);

end

%更改编码序列中的前两位,0变为1,1变为0,相当于错位function Codenumber1=yiweicodenumber(Codenumber) Codenumber1=[];

for i=1:2

if Codenumber(i)==0

Codenm=1;

else Codenumber(i)=0;

end;

end;

Codenumber1=Codenumber;

disp('错位后的编码序列:');

Codenumber1

数据结构哈夫曼编码译码器课程设计报告

JAVA语言实验报告 学院计算机工程学院班级计算1013 姓名佐伊伦学号 201081xxxx 成绩指导老师 xxxx 2012年09月03日

目录 目录 (1) 1 课程设计的目的和意义 (2) 2 需求分析 (3) 3 系统(项目)设计 (5) ①设计思路及方案 (5) ②模块的设计及介绍 (5) ③主要模块程序流程图 (8) 4 系统实现 (11) ①主调函数 (12) ②建立HuffmanTree (12) ③生成Huffman编码并写入文件 (15) ④电文译码 (16) 5 系统调试 (17) 参考文献 (21) 附录源程序 (22)

1 课程设计的目的和意义 在当今信息爆炸时代,如何采用有效的数据压缩技术来节省数据文件的存储空间和计算机网络的传送时间已越来越引起人们的重视。哈夫曼编码正是一种应用广泛且非常有效的数据压缩技术。 哈夫曼编码的应用很广泛,利用哈夫曼树求得的用于通信的二进制编码称为哈夫曼编码。树中从根到每个叶子都有一条路径,对路径上的各分支约定:指向左子树的分支表示“0”码,指向右子树的分支表示“1”码,取每条路径上的“0”或“1”的序列作为和各个对应的字符的编码,这就是哈夫曼编码。 通常我们把数据压缩的过程称为编码,解压缩的过程称为解码。电报通信是传递文字的二进制码形式的字符串。但在信息传递时,总希望总长度尽可能最短,即采用最短码。 作为信息管理专业的学生,我们应该很好的掌握这门技术。在课堂上,我们能过学到许多的理论知识,但我们很少有过自己动手实践的机会!课程设计就是为解决这个问题提供了一个平台。 在课程设计过程中,我们每个人选择一个课题,认真研究,根据课堂讲授内容,借助书本,自己动手实践。这样不但有助于我们消化课堂所讲解的内容,还可以增强我们的独立思考能力和动手能力;通过编写实验代码和调试运行,我们可以逐步积累调试C程序的经验并逐渐培养我们的编程能力、用计算机解决实际问题的能力。 在课程设计过程中,我们不但有自己的独立思考,还借助各种参考文献来帮助我们完成系统。更为重要的是,我们同学之间加强了交流,在对问题的认识方面可以交换不同的意见。同时,师生之间的互动也随之改善,我们可以通过具体的实例来从老师那学到更多的实用的知识。 数据结构课程具有比较强的理论性,同时也具有较强的可应用性和实践性。课程设计是一个重要的教学环节。我们在一般情况下都能够重视实验环节,但是容易忽略实验的总结,忽略实验报告的撰写。通过这次实验让我们明白:作为一名大学生必须严格训练分析总结能力、书面表达能力。需要逐步培养书写科学实验报告以及科技论文的能力。只有这样,我们的综合素质才会有好的提高。

哈夫曼树编码译码实验报告(DOC)

数据结构课程设计设计题目:哈夫曼树编码译码

目录 第一章需求分析 (1) 第二章设计要求 (1) 第三章概要设计 (2) (1)其主要流程图如图1-1所示。 (3) (2)设计包含的几个方面 (4) 第四章详细设计 (4) (1)①哈夫曼树的存储结构描述为: (4) (2)哈弗曼编码 (5) (3)哈弗曼译码 (7) (4)主函数 (8) (5)显示部分源程序: (8) 第五章调试结果 (10) 第六章心得体会 (12) 第七章参考文献 (12) 附录: (12)

在当今信息爆炸时代,如何采用有效的数据压缩技术节省数据文件的存储空间和计算机网络的传送时间已越来越引起人们的重视,哈夫曼编码正是一种应用广泛且非常有效的数据压缩技术。哈夫曼编码是一种编码方式,以哈夫曼树—即最优二叉树,带权路径长度最小的二叉树,经常应用于数据压缩。哈弗曼编码使用一张特殊的编码表将源字符(例如某文件中的一个符号)进行编码。这张编码表的特殊之处在于,它是根据每一个源字符出现的估算概率而建立起来的(出现概率高的字符使用较短的编码,反之出现概率低的则使用较长的编码,这便使编码之后的字符串的平均期望长度降低,从而达到无损压缩数据的目的)。哈夫曼编码的应用很广泛,利用哈夫曼树求得的用于通信的二进制编码称为哈夫曼编码。树中从根到每个叶子都有一条路径,对路径上的各分支约定:指向左子树的分支表示“0”码,指向右子树的分支表示“1”码,取每条路径上的“0”或“1”的序列作为和各个叶子对应的字符的编码,这就是哈夫曼编码。哈弗曼译码输入字符串可以把它编译成二进制代码,输入二进制代码时可以编译成字符串。 第二章设计要求 对输入的一串电文字符实现哈夫曼编码,再对哈夫曼编码生成的代码串进行译码,输出电文字符串。通常我们把数据压缩的过程称为编码,解压缩的过程称为解码。电报通信是传递文字的二进制码形式的字符串。但在信息传递时,总希望总长度能尽可能短,即采用最短码。假设每种字符在电文中出现的次数为Wi,编码长度为Li,电文中有n种字符,则电文编码总长度为∑WiLi。若将此对应到二叉树上,Wi为叶结点的权,Li为根结点到叶结点的路径长度。那么,∑WiLi 恰好为二叉树上带权路径长度。因此,设计电文总长最短的二进制前缀编码,就是以n种字符出现的频率作权,构造一棵哈夫曼树,此构造过程称为哈夫曼编码。设计实现的功能: (1) 哈夫曼树的建立; (2) 哈夫曼编码的生成; (3) 编码文件的译码。

哈夫曼编码资料

哈夫曼编码译码系统 一、需求分析 1、程序的基本功能: ①构造哈夫曼树及哈夫曼编码:从终端读入字符集大小n、n个字符以及n个对应的权 值,建立哈夫曼树;利用已将建好的哈弗曼树求每个叶结点的哈夫曼编码,并保存。 ②编码:利用已构造的哈弗曼编码对“明文”文件中的正文进行编码,然后将结果存 入“密文”文件中。 ③译码:将“密文”文件中的0、1代码序列进行译码。 ④打印“密文”文件:将文件以紧凑格式显示在终端上,同时,将此字符形式的编码 保存。 ⑤打印哈夫曼树:将已在内存中的哈夫曼以凹入表形式显示在终端上。 2、输入输出要求: ①从键盘接收字符集大小n、以及n个字符和n个权值; ②构造哈夫曼树:将HFMTree数组中的各个位置的各个域都添上相关的值,并将结构 体数组存入文件HTree.txt中。 ③打印哈夫曼树:从HFMTree数组读取相关的结点信息,以凹入表方式将各个结点画 出来; ④构造哈夫曼编码:先从文件HTree.txt中读入相关的字符信息进行哈夫曼编码,将字 符与其对应的编码存入文件HNode.txt中; ⑤编码:利用已构造的哈夫曼树对文件进行编码,打印结果,并将结果存入新建文件 中; ⑥译码:将密文文件中的内容利用HNode.txt中建立的编码规则进行翻译,打印结果, 并将结果存入新建文件中。 3、测试数据: 输入叶子结点个数为4,权值集合为{1,3,5,7},字符集合为{A,B,C,D},且字符集与权值集合一一对应。 二、概要设计 1、抽象数据类型的定义: ①采用静态链表作为哈夫曼树的存储结构; ②求哈夫曼编码时使用一维数组HCode作为哈夫曼编码信息的存储。 2、主模块的流程及各子模块的主要功能: ①int main() { 主菜单; swich语句结构选择; return 0; } ②in_park() { 输入车牌号; 若停车场已满,停入便道中,否则停入停车场; } ③output()

系统极化码的编译码算法研究

系统极化码的编译码算法研究 自Shannon有噪信道编码定理提出以来,信道编码技术飞速发展,以Turbo 码、LDPC码为代表的现代编码技术具有逼近Shannon限的误码性能,但是能够达到Shannon限的信道编码技术始终没有出现,极化码的出现打破了这一僵局。极化码由Arikan提出,且被证实其在二进制离散无记忆信道的渐进性能为Shannon 限。 根据构造方式的不同,极化码可分为非系统极化码与系统极化码,其中系统极化码具有更好的误码性能,但尚无明确的系统译码算法。当前大量的研究工作集中在非系统译码算法上,因此通常采用基于非系统译码与再编码的级联译码方案作为系统极化码的译码算法,这导致了系统极化码的译码延时较大。 针对系统极化码的译码问题,本文从编码及译码两个角度提出了改进算法,增强了系统极化码的通用性。在此基础上,本文考虑了资源有限型设备的情况,提出了一种低延时、低资源占用的系统译码方案。 本文的创新点如下:1、针对非系统译码的校验特性,提出了修正的系统编码方案。研究表明,该方案能简化再编码过程,其编码复杂度及误码性能与原系统编码方案一致,但能大幅度降低译码延时,增强了系统极化码的通用性。 2、针对尚无明确系统译码算法这一现状,提出了一种基于翻转序列校验的罗列连续消除系统译码方案。研究表明,该方案利用翻转序列校验消除了再编码过程,简化了译码流程,降低了译码时延,且其误码性能稍好于自适应的罗列连续消除算法。 3、针对低延时、低资源占用的微设备需求,提出了一种基于数组校验的罗列连续消除译码算法。研究表明,该方案利用数组校验实现了多重校验,解决了校验

滞后问题,降低了译码时延;使用了最佳路径剪枝策略,极大降低了空间资源占用;使用了直接映射方法,简化了系统编码前的数据预处理过程,并降低了信息获取的延时。 仿真表明,该方案能在性能损失较小的情况下极大降低译码延时、信息获取延时及资源占用。

哈夫曼编码译码系统实验报告,数据结构课程设计报告

v .. . .. 安徽大学 数据结构课程设计报告项目名称:哈弗曼编/译码系统的设计 与实现 姓名:鉏飞祥 学号:E21414018 专业:软件工程 完成日期 2016/7/4 计算机科学与技术学院

1 .需求分析 1.1问题描述 ?问题描述:利用哈夫曼编码进行通信可以大大提高信道利用率,缩短信息传输时间,降低传输成本。但是,这要求在发送端通过一个编码系统对待传数据预先编码,在接收端将传来的数据进行译码(解码)。对于双工信道(即可以双向传输信息的信道),每端都需要一个完整的编/译码系统。试为这样的信息收发站设计一个哈夫曼编译码系统。 1.2基本要求 (1)输入的形式和输入值的范围; (2)输出的形式; (3)程序所能达到的功能。 1.基本要求 (1)初始化(Initialzation)。从数据文件DataFile.data中读入字符及每个字符的权值,建立哈夫曼树HuffTree; (2)编码(EnCoding)。用已建好的哈夫曼树,对文件ToBeTran.data中的文本进行编码形成报文,将报文写在文件Code.txt中; (3)译码(Decoding)。利用已建好的哈夫曼树,对文件CodeFile.data中的代码进行解码形成原文,结果存入文件Textfile.txt中; (4)输出(Output)。输出DataFile.data中出现的字符以及各字符出现的频度(或概率);输出ToBeTran.data及其报文Code.txt;输出CodeFile.data

及其原文Textfile.txt; 2. 概要设计 说明本程序中用到的所有抽象数据类型的定义。主程序的流程以及各程序模块之间的层次(调用)关系。 (1)数据结构 哈夫曼树的节点 struct huff { int weight; int parent; int l; int r; }; 哈夫曼编码的存储 struct huff *hufftree; (2)程序模块 选择1到i-1中parent为0且权值最小的两个下标 void Select(struct huff *HT, int n, int &s1, int &s2) 构建哈夫曼树: void huffmancoding(struct huff *ht,int *w,int n)

哈夫曼编码与译码的实现

数据结构课程设计评阅书

2011—2012学年第一学期 专业:信息管理与信息系统学号: 1021024016 姓名:万永馨 课程设计名称:数据结构课程设计 设计题目:哈夫曼编码与译码的实现 完成期限:自 2012 年 2 月 20 日至 2012 年 3 月 2 日共 2 周 设计依据、要求及主要内容(可另加附页): 该设计题目将按以下要求完成: 哈夫曼编码与译码是信息传输中应用的经典算法,运用C或VC++结合数据结构等基础知识,按 以下要求编程实现各种进制的转换。 任务要求:1)阐述设计思想,画出流程图;2)需要对哈夫曼编码/译码的相关原理有所了解,设计数 据结构,建立必要的信息数据文件(最好存储成外部文件),并分析完成用户所需的基本操作功能;3)实现给定信息的编码和译码功能;4)应有较好的界面设计,说明程序测试方法;5)按照格式要 求完成课程设计说明书。 设计要求: 1)问题分析和任务定义:根据设计题目的要求,充分地分析和理解问题,明确问题要求做什么?(而不是怎么做?)限制条件是什么?确定问题的输入数据集合。 2)逻辑设计:对问题描述中涉及的操作对象定义相应的数据类型,并按照以数据结构为中心的 原则划分模块,定义主程序模块和各抽象数据类型。逻辑设计的结果应写出每个抽象数据类型的定 义(包括数据结构的描述和每个基本操作的功能说明),各个主要模块的算法,并画出模块之间的调 用关系图; 3)详细设计:定义相应的存储结构并写出各函数的伪码算法。在这个过程中,要综合考虑系统 功能,使得系统结构清晰、合理、简单和易于调试,抽象数据类型的实现尽可能做到数据封装,基 本操作的规格说明尽可能明确具体。详细设计的结果是对数据结构和基本操作做出进一步的求精, 写出数据存储结构的类型定义,写出函数形式的算法框架; 4)程序编码:把详细设计的结果进一步求精为程序设计语言程序。同时加入一些注解和断言, 使程序中逻辑概念清楚; 5)程序调试与测试:能够熟练掌握调试工具的各种功能,设计测试数据确保程序正确。调试正 确后,认真整理源程序及其注释,形成格式和风格良好的源程序清单和结果; 6)结果分析:程序运行结果包括正确的输入及其输出结果和含有错误的输入及其输出结果。算 法的时间、空间复杂性分析; 7)编写课程设计报告; 以上要求前三个阶段的任务完成后,将设计说明书的草稿交指导老师面审,审查合格方可进入 后续阶段的工作。设计工作结束,经指导老师验收合格后将设计说明书装订,并答辩。

Huffman编码报告

《数据结构》课程设计上机实习报告 课设题目Huffman编码和解码 班级 学生姓名 学号 指导教师 时间2015.12-2015.1

一、设计目的 1.进一步熟悉C语言开发环境,熟悉用C语言完成一个应用程序的设计过程,掌握有关编辑、调试和整合程序的方法和技巧。 2.通过此设计,了解《数据结构》课程中霍夫曼编码的的有关内容,明确其操作,熟悉其设计,同时学习到有关位向量的内容,对文件掌握加深 二、设计内容 Huffman编码与解码 (必做)(Huffman编码、二叉树) [问题描述] 对一篇英文文章(大于2000个英文字符),统计各字符出现的次 数,实现Huffman编码,以及对编码结果的解码。 [基本要求] (1)输出每个字符出现的次数和编码,其中求最小权值要求用堆实 现。 (2)在Huffman编码后,要将编码表和英文文章编码结果保存到文 件中,编码结果必须是二进制形式,即0 1的信息用比特位表示,不 能用字符’0’和’1’表示。 (3)提供读编码文件生成原文件的功能。 三、数据结构说明 在该程序中我仅仅使用了两个结构体来完成编码,用位域来实现bite流存储:const int MAXSIZE=300;//定义一次分配的Huffman储存单词最大量为500 const int OVERFLOW = 0; const int ERROR = 0; const int LineCountNum=500; typedef struct WordCount {

char Word;//存放字符 int freq; int parent , lchild , rchild;//存放亲子节点位置 int place;//用来保存第一次堆排序后,建立霍夫曼表前的相对位置 char *HuffmanCode;//存放霍夫曼编码 }WordCount , *WC;//存放单词结点的结构体 typedef struct HuffmanTree { WC w; int Number;//存储有多少数据存入 }HuffmanTree , *HTree; typedef struct { unsigned int a:1; }bite;//设置位段,存储一个bite //**************操作函数声明*********** void InitHuffmanTree(HTree &H);//初始化霍夫曼树 void HeapSort(WC &W , int Number , int choice);//堆排序核心函数 void HeapAdjust(WC &W , int down , int up , int choice);//堆排序调整函数,实现两种排序 void HuffmanCoding(HTree &H , WC &HT); //求霍夫曼树和霍夫曼编码表 void ShowHuffmanTree(HTree H);//输出霍夫曼树 void Select(WC &W , int i , int &s1 , int &s2);//选择1-i-1之间最小的两个数,且parent为0,用s1,s2返回 void GetTheDeCode(HTree H);//将编码结果写入函数 void PutTheDeCode(FILE *fp1 , FILE *fp2);//将编码结果解码得到文章 void CountTheWord(HTree &H , FILE *fp);//记录单词权值 void ShowTheEassy(FILE *wp);//展示文章 四、详细设计 1.首先我给出了编码和解码的菜单供其选择 2.在编码功能中,我先通过CountTheWord()函数进行单词权值记录,然后 进入编码功能,值得一提的是,编码时我给堆排序设计了两种排序形式——对权值的排序和对位置的排序,以达到选择两个最小的权值结点的最优时间复杂度的目的,此功能通过switch实现,但要给编码结构体中放置一个place 空间,这也从侧面反映了时间和空间矛盾的地方(值得一提的是,有些编码并不可见且有特殊含义,如换行符,所以将字符放入文件中时,并不对其进行处理,读出是进行顺序读出) 3.编码结束后将编码结果,对应字符分别存放在文件中,然后对整篇文章进行 编码

huffman编码译码实现文件的压缩与解压.

数据结构 课程设计 题目名称:huffman编码与解码实现文件的压缩与解压专业年级: 组长: 小组成员: 指导教师: 二〇一二年十二月二十六日

目录 一、目标任务与问题分析 (2) 1.1目标任务 (2) 1.2问题分析 (2) 二、算法分析 (2) 2.1构造huffman树 (2) 2.1.1 字符的统计 (2) 2.1.2 huffman树节点的设计 (2) 2.2构造huffman编码 (3) 2.2.1 huffman编码的设计 (3) 2.3 压缩文件与解压文件的实现 (3) 三、执行效果 (4) 3.1界面 (4) 3.2每个字符的编码 (4) 3.3操作部分 (5) 3.4文件效果 (6) 四、源程序 (7) 五、参考文献 (16)

huffman编码与解码实现文件的压缩与解压 一、目标任务与问题分析 1.1目标任务 采用huffman编码思想实现文件的压缩和解压功能,可以将任意文件压缩,压缩后也可以解压出来。这样即节约了存储空间,也不会破坏文件的完整性。 1.2问题分析 本问题首先应该是利用哈夫曼思想,对需要压缩的文件中的个字符进行频率统计,为了能对任意的文件进行处理,应该所有的文件以二进制的方式进行处理,即对文件(不管包含的是字母还是汉字)采取一个个的字节处理,然后根据统计的频率结果构造哈夫曼树,然后对每个字符进行哈夫曼编码,然后逐一对被压缩的文件的每个字符构建的新的哈夫曼编码存入新的文件中即得到的压缩文件。解压过程则利用相应的哈夫曼树及压缩文件中的二进制码将编码序列译码,对文件进行解压,得到解压文件。 二、算法分析 2.1构造huffman树 要利用哈夫曼编码对文本文件进行压缩,首先必须知道期字符相应的哈夫曼编码。为了得到文件中字符的频率,一般的做法是扫描整个文本进行统计,编写程序统计文件中各个字符出现的频率。由于一个字符的范围在[0-255]之间,即共256个状态,所以可以直接用256个哈夫曼树节点即数组(后面有节点的定义)空间来存储整个文件的信息,节点中包括对应字符信息,其中包括频率。 2.1.1 字符的统计 用结构体huffchar来存放文件字符的信息。其中有文件中不同字符出现的种类Count、字符data。 struct huffchar{ //存放读入字符的类; int Count;//字符出现的个数; char data;//字符; }; 函数实现: bool char_judge(char c)//判断字符出现的函数; void char_add(char c)//添加新出现的字符; void read_file_count() //文件的读取 2.1.2 huffman树节点的设计 用结构体huff_tree来存储结点信息,其中有成员频率weight、父亲节点parent、左儿子节点lchild、右儿子节点rchild。

哈夫曼树的编码和译码

#include"stdafx.h" #include"stdio.h" #include"conio.h" #include #include #include using namespace std; #define maxbit 100 #define Maxvalue 2000//最大权值整数常量#define Maxleaf 100//最大叶子结点数 #define size 300//0、串数组的长度 static int n;//实际的叶子结点数 struct HNodeType { int weight; int parent; int lchild; int rchild; int ceng;//结点相应的层数 char ch;//各结点对应的字符 }; struct HCodeType { int bit[maxbit];//存放编码的数组 int start;//编码在数组中的开始位置}; static HNodeType *HuffNode;//定义静态指针HNodeType *init()//初始化静态链表 { HuffNode=new HNodeType[2*n-1]; for(int i=0;i<2*n-1;i++) { HuffNode[i].weight=0; HuffNode[i].parent=-1; HuffNode[i].lchild=-1; HuffNode[i].rchild=-1; HuffNode[i].ceng=-1; HuffNode[i].ch='0'; } return HuffNode; }

霍夫曼编码表

附录二 表1. 传真用的修正霍夫曼编码表 构造码 64 11011 0000001111 960 011010100 0000001110011 128 10010 000011001000 1024 011010101 0000001110100 192 010111 000011001001 1088 011010110 0000001110101 256 0110111 000001011011 1152 011010111 0000001110110 320 00110110 000000110011 1216 011011000 0000001110111 384 00110111 000000110100 1280 011011001 0000001010010 448 01100100 000000110101 1344 011011010 0000001010011 512 01100101 0000001101100 1448 011011011 0000001010100 576 01101000 0000001101101 1472 010011000 0000001010101 640 01100111 0000001001010 1536 010011001 0000001011010 704 011001100 0000001001011 1600 010011010 0000001011011 768 011001101 0000001001100 1664 011000 0000001100100 832 011010010 0000001001101 1728 010011011 0000001100101 896 011010011 0000001110010 EOL 000000000001 000000000001 结尾码 游程长度 白游程编码 黑游程编码 游程长度白游程编码 黑游程编码 0 00110101 0000110111 32 000111011 000001101010 1 000111 010 33 00010010 000001101011 2 0111 11 34 00010011 000011010010 3 1000 10 35 00010100 000011010011 4 1011 011 36 00010101 000011010100 5 1100 0011 37 00010110 000011010101 6 1110 0010 38 00010111 000011010110 7 1111 00011 39 00101000 000011010111 8 10011 000101 40 00101001 000001101100 9 10100 000100 41 00101010 000001101101 10 00111 0000100 42 00101011 000011011010 11 01000 0000101 43 00101100 000011011011 12 001000 0000111 44 00101101 000001010100 13 000011 00000100 45 00000100 000001010101 14 110100 00000111 46 00000101 000001010110 15 110101 000011000 47 00001010 000001010111 16 101010 0000010111 48 00001011 000001100100 17 101011 0000011000 49 01010010 000001100101 18 0100111 0000001000 50 01010011 000001010010 19 0001100 00001100111 51 01010100 000001010011 20 0001000 00001101000 52 01010101 000000100100 21 0010111 00001101100 53 00100100 000000110111 22 0000011 00000110111 54 00100101 000000111000 23 0000100 00000101000 55 01011000 000000100111 24 0101000 00000010111 56 01011001 000000101000 25 0101011 00000011000 57 01011010 000001011000 26 0010011 000011001010 58 01011011 000001011001 27 0100100 000011001011 59 01001010 000000101011 28 0011000 000011001100 60 01001011 000000101100 29 00000010 000011001101 61 00110010 000001011010 30 00000011 000001101000 62 00110011 000001100110 31 00011010 000001101001 63 00110100 000001100111 205

哈夫曼编码译码的设计与实现数据结构课程设计

《数据结构》课程设计题目--哈夫曼编码/译码的设计与实现 班级:13数据库一班 学号:1315925280 姓名:吴松 指导教师:王超

目录 目录 (1) 一、需求分析 (2) 二、设计要求 (2) 三、概要设计 (2) 1、流程图 (2) 2、设计包含的几个部分 (4) 四、详细设计 (2) 五、显示结果………………………………………………9. 六、心得体会 (10) 七、参考文献 (11) 哈夫曼编码译码 一、需求分析

在当今信息爆炸时代,如何采用有效的数据压缩技术节省数据文件的存储空间和计算机网络的传送时间已越来越引起人们的重视,赫夫曼编码正是一种应用广泛且非常有效的数据压缩技术。哈夫曼编码是一种编码方式,以哈夫曼树—即最优二叉树,带权路径长度最小的二叉树,经常应用于数据压缩。哈弗曼编码使用一张特殊的编码表将源字符(例如某文件中的一个符号)进行编码。这张编码表的特殊之处在于,它是根据每一个源字符出现的估算概率而建立起来的(出现概率高的字符使用较短的编码,反之出现概率低的则使用较长的编码,这便使编码之后的字符串的平均期望长度降低,从而达到无损压缩数据的目的)。赫夫曼编码的应用很广泛,利用赫夫曼树求得的用于通信的二进制编码称为赫夫曼编码。树中从根到每个叶子都有一条路径,对路径上的各分支约定:指向左子树的分支表示“0”码,指向右子树的分支表示“1”码,取每条路径上的“0”或“1”的序列作为和各个叶子对应的字符的编码,这就是赫夫曼编码。哈弗曼译码输入字符串可以把它编译成二进制代码,输入二进制代码时可以编译成字符串。 二、设计要求 对输入的一串电文字符实现赫夫曼编码,再对赫夫曼编码生成的代码串进行译码,输出电文字符串。通常我们把数据压缩的过程称为编码,解压缩的过程称为解码。电报通信是传递文字的二进制码形式的字符串。但在信息传递时,总希望总长度能尽可能短,即采用最短码。假设每种字符在电文中出现的次数为Wi,编码长度为Li,电文中有n种字符,则电文编码总长度为∑WiLi。若将此对应到二叉树上,Wi为叶结点的权,Li为根结点到叶结点的路径长度。那么,∑WiLi 恰好为二叉树上带权路径长度。因此,设计电文总长最短的二进制前缀编码,就是以n种字符出现的频率作权,构造一棵赫夫曼树,此构造过程称为赫夫曼编码。设计实现的功能: (1) 赫夫曼树的建立; (2) 赫夫曼编码的生成; (3) 编码文件的译码。 三、概要设计 哈夫曼编\译码器的主要功能是先建立哈夫曼树,然后利用建好的哈夫曼树生成哈夫曼编码后进行译码。 在数据通信中,经常需要将传送的文字转换成由二进制字符0、1组成的二进制串,称之为编码。构造一棵哈夫曼树,规定哈夫曼树中的左分之代表0,右分支代表1,则从根节点到每个叶子节点所经过的路径分支组成的0和1的序列便为该节点对应字符的编码,称之为哈夫曼编码。 最简单的二进制编码方式是等长编码。若采用不等长编码,让出现频率高的字符具有较短的编码,让出现频率低的字符具有较长的编码,这样可能缩短传送电文的总长度。哈夫曼树课用于构造使电文的编码总长最短的编码方案。 (1)其主要流程图如图1-1所示。

哈夫曼编码与译码器_数据结构课程设计报告

沈阳航空航天大学 课程设计报告 课程设计名称:数据结构课程设计 课程设计题目:实现哈夫曼编码和译码器 院(系):计算机学院 专业:计算机科学与技术 班级:24010102 学号:2012040101082 姓名:尹伟和 指导教师:徐蕾

此页为任务书

目录 1.题目分析 (1) 1.1.题目重述 (1) 1.1.1.系统功能需求分析 (1) 2.程序设计 (2) 2.1.系统功能模块说明 (2) 2.1.1.系统功能模块结构 (2) 2.1.2.系统模块功能说明 (3) 2.2.数据结构说明 (3) 2.2.1.结构体定义说明 (3) 2.2.2.哈夫曼树 (4) 2.2.3.字符-哈夫曼编码对照表 (4) 2.3.函数说明 (4) 3.算法描述 (6) 3.1.哈夫曼树的构建 (6) 3.2.字符-哈夫曼编码对照表 (6) 3.3.编码 (6) 3.4.译码 (7) 4.程序测试 (9) 4.1.字符集输入 (9) 4.2.编码测试 (10) 4.3.译码测试 (11) 参考文献 (13) 附录(程序清单) (14)

沈阳航空航天大学课程设计报告 1.题目分析 1.1.题目重述 本次课程设计的目标是实现一个哈夫曼编码和译码器。该哈夫曼编码和译码器需要根据用户输入的字符集及相应字符出现的频率,对字符集所包含的字符进行哈夫曼编码。同时,作为编码器需要其对用户提供的明文字符串进行编码,使明文字符串变为二进制密文;作为译码器需要对用户提供的二进制密文进行译码,使二进制密文变为字符明文。 1.1.1.系统功能需求分析 通过对课程设计的题目分析,可以得出哈夫曼编码和译码器的功能需求,需求如下: 1)读取用户输入的字符集和相应字符出现的频率; 2)根据用户输入构建哈夫曼树; 3)根据哈夫曼树构建字符-哈夫曼编码对照表; 4)根据字符-哈夫曼编码对照表对明文字符串进行编码; 5)根据哈夫曼树对二进制密文进行译码。

LDPC信道编译码算法研究

河北工业大学本科毕业设计(论文)前期报告 毕业设计(论文)题目: LDPC信道编译码算法研究 专业(方向):通信工程 学生信息: 学号:112198 姓名:杨昌兆班级:通信112 指导教师信息: 姓名:高军萍职称:副教授 报告提交日期:2015年3月11日 文献综述 通信系统最基本目的就是将信息从信源高效、可靠、以及安全地传送到信宿,所以有噪声干扰的通信信道不可避免地会对信道中传输的信息产生一定程度的干扰,这就可能降低通信的可靠性。以前人们认为通信系统的可靠性与有效性是一对无法调和的矛盾,一方的改善总会导致另一方受到损害,直到Shannon 信息和编码理论的奠基性论文“通信的数学理论”于1948年发表之后,人们才逐渐改变了这一观点。他在论文中首次提出了在有扰信道上实现可靠通信的一些方法,这就是通过信源信道的编码。 目前广泛使用的信道编码技术有,奇偶校验码、行列监督码、恒比码、汉明码、循环码(CRC)等编码技术。信道编码的本质是增加通信的可靠性,或者说增加整个系统的抗干扰性。对信道编码有以下要求:1.透明性:要求对所传消息的内容不加任何限制;2.有纠错能力;3.效率高:为了与信道频谱匹配和具有纠错能力,通常要向原信号添加一些码,要求加入最少的比特数而得到最大的利益;4.包含适当的定时信息。LDPC码就是其中的一种方式,它具有很多优势和特点。 根据 Shannon 提出的信道编码理论[1],他指出只要信息的传输速率低于信道容量C,就必然会存在一种编码方法,能使得信息出现差错的概率趋于0;这就是著名的信道编码定理。但遗憾的是Shannon 信道编码理论并没有指出具体的那一种编码方式能够实现码元传输速率逼近信道容量。 直到1962 年,Gallager在他的博士论文中提出了LDPC编码[2][3],但由于当时的计算能力,人们认为LDPC码不实用。直到Turbo码的出现,LDPC码才重新受到了人们的重视[5][6]。Tanner在他的一篇的文章中正式提出了用图模型来描述码字的概念,从而将LDPC码的校验矩阵对应到被称为Tanner图[7][8]的双向二部图上。采用Tanner图构造的LDPC码,通过并行译码可以显著地降低译码复杂度。Turbo码的发现重新引发了众多学者对LDPC码的研究兴趣。 后来MacKay和Neal利用随机构造的Tanner图研究了LDPC码的性能,发现采用和积译码算法的正则LDPC码具有和Turbo码相似的译码性能,在长码时甚至超过了Turbo码[9][10],这一结果引起了信道编码界的极大关注。此后,Davey和MacKay从减少Tanner图上小环路的概念出发提出了基于GF (q),q >2的LDPC码[11][12],进一步提高了LDPC码的译码性能。

哈夫曼编码和译码系统

通达学院 算法与数据结构程序设计 题目:哈夫曼编码和译码系统 专业 学生姓名 班级学号 指导教师 指导单位 日期

教师评语 同学出勤率(满勤、较高、一般,较低),学习态度(端正、较端正、一般、较差),程序设计基础(好、较好、一般、较差),演示程序(已经、没有)达到了基本要求,算法设计(好、较好、一般),界面友好程度(好、较好、一般),答辩过程中回答问题(准确、较准确、错误率较高),撰写报告格式(规范、一般)、内容(丰满、简单)、表述(清晰、一般、不清楚),(圆满、较好、基本)完成了课题任务。 教师签名: 年月日 成绩评定 备注

一、题目要求: 题 目 :哈夫曼编码和译码系统 基本要求: (1) 能输入字符集和各字符频度建立哈夫曼树; (2) 产生各字符的哈夫曼编码,并进行解码。 提高要求: (1) 能设计出简捷易操作的窗口界面; (2) 编码和译码存储在文件中。 二、需求分析: 2.1基本思想 根据,哈夫曼的定义,一棵二叉树要使其带权路径长度最小,必须使权值越大的叶子结点越靠近根结点,而权值越小的叶子结点越远离根结点.依据这个特点便提出了哈夫曼算法,其基本思想是: (1) 初始化:由给定的n 个权值{w 1, w 2,…, w n }构造n 棵只有一个根结点的二叉树,从而得到一个二叉树集合F={ T 1,T 2,…,T n }; (2) 选取与合并:在F 中选取根结点的权值最小的两棵二叉树分别作为左、右子树构造一颗新的二叉树,这棵新二叉树的根结点的权值为其左、右子树根结点的权值之和; (3) 删除与加入:在F 中删除作为左、右子树的两棵二叉树,并将新建立的二叉树加入到F 中; (4) 重复(2)、(3)两步,当集合F 中只剩下一棵二叉树时,这棵二叉树便是哈夫曼树. 2.2存储结构 在由哈夫曼算法构造的哈夫曼树中,非叶子结点的度均为2,根据二叉树的性质可知,具有n 个叶子结点的哈夫曼树共有2n-1个结点,其中有n-1个非叶子结点,它们是在n-1次的合并过程中生成的.为了便于选取根结点权值最小的二叉树以及合并操作,设置一个数组HuffmanNode[2n-1]保存哈夫曼树中各结点的信息,数组元素的结点结构如图所示. 图 哈夫曼树的结点结构 其中: weight parent lchild rchild i nf

霍夫曼编码

霍夫曼编码 霍夫曼编码(Huffman Coding)是一种编码方法,霍夫曼编码是可变字长编码(VLC)的一种。1952年,David A. Huffman在麻省理工攻读博士时所提出一种编码方法,并发表于《一种构建极小多余编码的方法》(A Method for the Construction of Minimum-Redundancy Codes)一文。 该方法完全依据字符出现概率来构造异字头的平均长度最短的 码字,有时称之为最佳编码,一般就叫作Huffman编码。 在计算机数据处理中,霍夫曼编码使用变长编码表对源符号(如文件中的一个字母)进行编码,其中变长编码表是通过一种评估来源符号出现机率的方法得到的,出现机率高的字母使用较短的编码,反之出现机率低的则使用较长的编码,这便使编码之后的字符串的平均长度、期望值降低,从而达到无损压缩数据的目的。1951年,霍夫曼和他 在MIT信息论的同学需要选择是完成学期报告还是期末考试。 导师Robert M. Fano给他们的学期报告的题目是,查找最有效的二进制编码。由于无法证明哪个已有编码是最有效的,霍夫曼放弃对已有编码的研究,转向新的探索,最终发现了基于有序频率二叉树编码的想法,并很快证明了这个方法是最有效的。由于这个算法,学生终于青出于蓝,超过了他那曾经和信息论创立者克劳德·香农共同研究过类似编码的导师。霍夫曼使用自底向上的方法构建二叉树,避免了次优算法Shannon-Fano编码的最大弊端──自顶向下构建树。 霍夫曼(Huffman)编码是一种统计编码。属于无损(lossless)压缩编码。

以霍夫曼树─即最优二叉树,带权路径长度最小的二叉树,经常应用于数据压缩。 ←根据给定数据集中各元素所出现的频率来压缩数据的 一种统计压缩编码方法。这些元素(如字母)出现的次数越 多,其编码的位数就越少。 ←广泛用在JPEG, MPEG, H.2X等各种信息编码标准中。霍夫曼编码的步骤 霍夫曼编码的具体步骤如下: 1)将信源符号的概率按减小的顺序排队。 2)把两个最小的概率相加,并继续这一步骤,始终将较高的概率分支放在上部,直到最后变成概率1。 3)将每对组合的上边一个指定为1,下边一个指定为0(或相反)。4)画出由概率1处到每个信源符号的路径,顺序记下沿路径的0和1,所得就是该符号的霍夫曼码字。 信源熵的定义: 概率空间中每个事件所含有的自信息量的数学期望称信源熵或简称熵(entropy),记为: 例:现有一个由5个不同符号组成的30个符号的字 符串:BABACACADADABBCBABEBEDDABEEEBB 计算 (1) 该字符串的霍夫曼码 (2) 该字符串的熵 (3) 该字符串的平均码长

哈夫曼编码与译码报告

一、设计思想 程序要求: 利用哈夫曼树对字符串进行编码,要求每个字符有自己唯一的编码。将得到的一串字串译成0、1编码后存到一个文件夹中,然后再从这个文件夹中读出这串编码进行解码。 实现方法: 输入一串字符,要求字符的区间为大写的26个英文字母,将获得的串字符用计算权值的函数(jsquanzhi())进行字符统计,统计出现的字符种数以及每种字符出现的次数,将该种字符出现的次数作为它的权值。将出现的字符的权值和该字符依次分别赋给两个结构体HT和HC,利用HT(节点)权值的大小建立哈夫曼树,首先用选择函数select()函数选择两个权值最小的字符作为叶子节点,创建一个新的节点作为这两个叶节点的父节点,被选中的节点给他的HT[i].parent赋值是他下次不再被选中,父节点的权值为,子节点的权值之和。然后将该将父节点放入筛选区中,再进行选择(被选过的不再被使用),直到所有的节点都被使用,这样一个哈夫曼树就被建立了。根据每个字符在哈夫曼书中的位置来编译每个字符的0、1密文代码,从叶节点判断该叶节点是其父节点的左右字左字为‘0’,右子为‘1’,在判断父节点是上级父节点的左右子直至根节点,将生成的0、1字符串按所表示的字符倒序存入HC相应的字符的bins[]数组。 重新一个一个字符的读取输入的字符串,按照字符出现的顺序将它转为0、1代码并存到一个txt文件夹中去。解码时从文件夹中,一个一个字符的读出那串0、1代码赋给一个临时字符串cd[],用该字符串与每个字符的HC[i].bins密文比较,直到与一个字符的密文相同时,译出该字符,将字符存放在临时字符数组tempstr[]中,清空临时字符串继续读取0、1代码进行翻译,直至文件密文结束为止。于是就得到了原先被加密的那串字符串。

相关文档
最新文档