北邮数据结构实验Huffman编码解码器Word下载.docx

上传人:b****5 文档编号:21164661 上传时间:2023-01-28 格式:DOCX 页数:12 大小:46.43KB
下载 相关 举报
北邮数据结构实验Huffman编码解码器Word下载.docx_第1页
第1页 / 共12页
北邮数据结构实验Huffman编码解码器Word下载.docx_第2页
第2页 / 共12页
北邮数据结构实验Huffman编码解码器Word下载.docx_第3页
第3页 / 共12页
北邮数据结构实验Huffman编码解码器Word下载.docx_第4页
第4页 / 共12页
北邮数据结构实验Huffman编码解码器Word下载.docx_第5页
第5页 / 共12页
点击查看更多>>
下载资源
资源描述

北邮数据结构实验Huffman编码解码器Word下载.docx

《北邮数据结构实验Huffman编码解码器Word下载.docx》由会员分享,可在线阅读,更多相关《北邮数据结构实验Huffman编码解码器Word下载.docx(12页珍藏版)》请在冰豆网上搜索。

北邮数据结构实验Huffman编码解码器Word下载.docx

parent

2・2程序流程(或程序结构、或类关系图等表明程序构成的内容,一般为流程

图等)

221.流程图

开始

输入进行编码的字符串

统计各个字符的频度,并对各叶子节点的权重赋值

初始化各节点的Lchild,Rchild和parent

进行哈弗曼编码

该节点是否为根节点

对字符串进行编码

找到当前字符编码,复制到总编码中

是否最后一个字符

输岀各字符串编码

对哈弗曼码进行译码

输岀译码结果

计算分析内存占用情况

 

if

输出占用情况

结束

2.2.1.伪代码

1.输入进行编码的字符串

2•遍历字符串,并为叶子节点权重赋值

3.依次对各字符进行哈弗曼编码,自下往上,若是双亲节点左孩子则编码前插入’0'

若是双亲节点右孩子则编码钱插入’1'

4.显示各字符的哈弗曼编码。

5.对字符串进行编码,挨个遍历字符,找到相应的编码,复制到总的编码里,最后输出字符串的编码

6.对字符串的哈弗曼码进行译码。

自上往下,若是‘0'

则递归到左孩子,若是‘1'

则递归到右孩子,知道叶子节点,输出该叶子节点代表字符,再继续遍历。

7•分析内存占用情况。

若用ASCII编码,每个字符占1个字节,即8bit,该情况下占用内存就是(字符长度)*8。

若用哈弗曼编码,占用内存是各(字符频度)*(每个字符占用位数)之和。

2.3关键算法分析

该程序关键算法即哈弗曼编码,语句如下:

voidCHTree:

:

huffmancode()

{

inti;

if(n<

=1)return;

m=2*n-1;

for(i=1;

i<

=n;

i++)〃叶子节点的初始化

{ht[i].parent=0;

ht[i]」child=0;

ht[i].rchild=0;

}

for(;

=m;

i++)//非叶子节点的初始化

ht[i].weight=0;

ht[i].parent=0;

ht[i].lchild=0;

for(i=n+1;

++i)〃构造哈夫曼树

s1=select(i-l);

//函数在ht[1]到ht[i-1]中选择parent为0且weight最小的结点,并将结

点序号返s,并将ht[s1].parent设为-1

s2=select(i-1);

ht[s1].parent=i;

ht[s2].parent=i;

ht[i]」child=s1;

ht[i].rchild=s2;

ht[i].weight=ht[s1].weight+ht[s2].weight;

intc,f;

++i){

for(c=i,f=ht[i].parent;

f!

=O;

c=f,f=ht[f].parent)〃逆向求叶子结点的哈夫曼编码

if(ht[f].lchild==c){

str[i].insert(0,"

0"

0,1);

}//在字符串str[i]的第0位置插入字符“0”

else{

1"

}//在字符串str[i]的第0位置插入字符“1”}

分析:

这段语句实现的功能是根据统计出来的各字符的频度,建立哈弗曼。

建立哈弗曼

树的过程如程序所展示,每次选取权重最小且无双亲节点的节点组合,并将其权重之和赋给

其双亲节点,加入到总结中进行下次判断。

哈弗曼树建立完全以后,开始对各字符进行编码,

从下往上,以叶子节点为起始点,若它是双亲节点的左孩子,其编码前插入’0'

若是右孩

子则插入‘1'

再判断双亲节点使其双亲节点的左孩子还是右孩子,以此类推直到根节点。

依次对每个字符进行上述过程编码。

算法复杂度:

最好情况为只有根结点和叶子节点:

O(n)

最坏情况为满二叉树情况:

O(n*logn/2

3•程序运行结果分析

Rr码译咼uln'

FT輿诃*析riiH=1%

请轿乂己同词的宇符串日扯咅门冋日吉片也出ph

竺i璇迦I-S宇行飞喰1&

^9

SUfieVAdrp詁isfratB內dgjEfit計vfemilswdi-DJ0lC\PWjedt5?

\hulfEajcWebug'

JhSiwr^

首先,要求用户输入进行编码的字符串,遍历字符串,并为叶子节点权重赋值。

然后,依次

对各字符进行哈弗曼编码,自下往上,若是双亲节点左孩子则编码前插入’0'

若是双亲节

点右孩子则编码钱插入’1'

屏幕上显示各字符的哈弗曼编码。

接下来对字符串进行编码,挨个遍历字符,找到相应的编码,复制到总的编码里,最后输出字符串的编码。

对字符串的哈弗曼码进行译码。

自上往下,若是’0'

则递归到左孩子,若是’1'

则递归到右孩子,

知道叶子节点,输出该叶子节点代表字符,再继续遍历。

最后分析内存占用情况。

若用ASCII编码,每个字符占1个字节,即8bit,该情况下占用内存就是(字符长度)*8。

若用哈弗曼

编码,占用内存是各(字符频度)*(每个字符占用位数)之和。

3.总结

4.1实验的难点和关键点

本实验的难点和关键点是进行哈弗曼的编码与译码。

编码之前先要遍历字符串,并统计

各字符出现的频度。

这里就要区分目前的字符是否出现过,若出现过则字符权重加一,若没

有出现则在结构体数组的当前末尾添加该元素。

统计完频度以后开始编码。

根据哈弗曼树的

特点,每次选取结点里权重最小,且双亲不为0的节点结合,依次添加直至根节点。

编码过

程是从下往上。

对于某字符所在叶子节点,若是双亲节点左孩子则编码前插入’0'

若是双

亲节点右孩子则编码钱插入’1'

直到双亲节点移动到根节点,所得到的编码即为该字符的

编码。

译码过程是编码的逆过程。

依次读取哈弗曼码,自上往下,若是‘0'

则递归到左孩子,若是‘1'

则递归到右孩子,知道叶子节点,输出该叶子节点代表字符,再继续遍历。

4.2心得体会

并且熟悉了这种数

通过哈弗曼树的程序编写,更加深入了解了树这种数据结构的特点,据结构的应用。

同时,也对哈弗曼编码的优越性能有了根本的解释。

附:

程序代码

#include<

iostream>

string>

usingnamespacestd;

#definemax1000〃哈夫曼数存储的最大叶子节点数intjudge;

//初始化过程中用于判断字符是否出现过structHTNode

charc;

intweight;

intlchild,rchild,parent;

};

classCHTree

public:

CHTree(){ht=NULL;

voidInit();

voidhuffmancode();

intselect(inti);

voidDisplay();

voidcanculate();

voidencoding();

voiddecoding();

private:

HTNode*ht;

intm;

intn;

//叶子结点数

ints1;

ints2;

stringa;

//存储输入的字符串

stringcode;

//存储对字符串的编码

stringstr[max];

〃存储叶子结点的哈夫曼编码};

lnit()

inti=1;

〃用于记录叶子节点个数

intj=0;

intx=O,ru;

cout<

<

"

请输入进行编码的字符串:

"

endl;

cin>

>

a;

intl=a.length();

ht=(HTNode*)malloc((max)*sizeof(HTNode));

〃分配MAXSIZE个叶子结点的存储空间while(x<

l)//统计字符出现的次数

judge=1;

for(j=0;

j<

i;

j++){

if(ht[j].c==a[x]){〃如果字符a[x]已经出现过,则记录,权值加1

ht[j].weight++;

judge=0;

break;

if(judge){〃若字符没有出现过,字符入列,且权值设为1

n=i;

〃记录叶子节点数

ht[i].weight=1;

ht[i].c=a[x];

i++;

}

x++;

intCHTree:

select(inti)//函数在ht[1]到ht[i]中选择parent为0且weight最小的结点,并将结点序号返回

intj=1;

intk=1;

ints;

while(ht[j].parent!

=O){

j++;

s=j;

k=j+1;

while(k<

=i)

while(ht[k].parent!

=0)k++;

if(k>

i)returns;

if(ht[j].weight>

ht[k].weight){

ht[j].parent=O;

〃如果第二次和第二次以后循环中发现有比ht[j]权值还小的,将

ht[j].parent重新设为0

j=k;

〃始终令“ht[j]”为二者中权值小的那一个

ht[j].parent=-1;

〃如果ht[j]是权值较小的,将ht[j]的parent记为-1,

k++;

returns;

{ht[i].parent=O;

ht[i].parent=O;

s1=select(i-1);

〃函数在ht[1]到ht[i-1]中选择parent为0且weight最小的结点,并将结

ht[i].lchild=s1;

str[i].insert(O,"

O"

O,1);

Display(){

huffman编码如下:

\n"

;

字符"

'

\t'

权值"

哈夫曼编码"

endl;

for(inti=1;

=n;

i++){

ht[i].c<

ht[i].weight<

str[i]<

canculate(){

intm=0;

m+=(ht[i].weight)*(str[i].length());

〃该字符所占位数为频度和每个字符huffman码长

度乘积

\n\n内存分析:

原始编码所占内存数为

8*sizeof(char)*(a.length())<

bit"

huffman编码所占内存数为"

m<

encoding(){

for(inti=0;

a.length();

i++){〃循环变量i用于遍历输入字符串的字符

for(intj=1;

j++){〃循环变量j用于寻找huffman编码中与该字符的相匹配的字符

编码

if(a[i]==ht[j].c)code+=str[j];

\n\n字符编码为"

code<

decoding(){

inti=0;

intm=code」ength();

\n\n对编码译码后所得字符:

while(i<

m){

intparent=2*n-1;

〃根结点在HTree中的下表

while(ht[parent].rchild!

=O||ht[parent].lchild!

=O)〃自根结点向叶子节点匹配编码,叶子

节点左右孩子均为0,此时输出字符

if(code[i]=='

0'

parent=ht[parent].lchild;

else

parent=ht[parent].rchild;

ht[parent].c;

voidmain()

CHTreeh;

h.lnit();

//初始化,统计输入字符的频度,赋值各叶子节点的权重h.huffmancode();

〃建立huffman树

h.Display();

〃显示各字符对应的huffman码

h.encoding();

〃对输入的字符进行编码

h.decoding();

〃对以上编码进行解码

h.canculate();

〃计算分析编码前与编码后的所占内存system("

pause"

);

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > PPT模板 > 其它模板

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1