哈夫曼编码Word文档下载推荐.docx

上传人:b****1 文档编号:3111672 上传时间:2023-05-01 格式:DOCX 页数:21 大小:355.43KB
下载 相关 举报
哈夫曼编码Word文档下载推荐.docx_第1页
第1页 / 共21页
哈夫曼编码Word文档下载推荐.docx_第2页
第2页 / 共21页
哈夫曼编码Word文档下载推荐.docx_第3页
第3页 / 共21页
哈夫曼编码Word文档下载推荐.docx_第4页
第4页 / 共21页
哈夫曼编码Word文档下载推荐.docx_第5页
第5页 / 共21页
哈夫曼编码Word文档下载推荐.docx_第6页
第6页 / 共21页
哈夫曼编码Word文档下载推荐.docx_第7页
第7页 / 共21页
哈夫曼编码Word文档下载推荐.docx_第8页
第8页 / 共21页
哈夫曼编码Word文档下载推荐.docx_第9页
第9页 / 共21页
哈夫曼编码Word文档下载推荐.docx_第10页
第10页 / 共21页
哈夫曼编码Word文档下载推荐.docx_第11页
第11页 / 共21页
哈夫曼编码Word文档下载推荐.docx_第12页
第12页 / 共21页
哈夫曼编码Word文档下载推荐.docx_第13页
第13页 / 共21页
哈夫曼编码Word文档下载推荐.docx_第14页
第14页 / 共21页
哈夫曼编码Word文档下载推荐.docx_第15页
第15页 / 共21页
哈夫曼编码Word文档下载推荐.docx_第16页
第16页 / 共21页
哈夫曼编码Word文档下载推荐.docx_第17页
第17页 / 共21页
哈夫曼编码Word文档下载推荐.docx_第18页
第18页 / 共21页
哈夫曼编码Word文档下载推荐.docx_第19页
第19页 / 共21页
哈夫曼编码Word文档下载推荐.docx_第20页
第20页 / 共21页
亲,该文档总共21页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

哈夫曼编码Word文档下载推荐.docx

《哈夫曼编码Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《哈夫曼编码Word文档下载推荐.docx(21页珍藏版)》请在冰点文库上搜索。

哈夫曼编码Word文档下载推荐.docx

执行结果14

十一:

体会感想16

哈夫曼树

给定n个权值作为n个叶子结点,构造一棵二叉树,若带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffmantree)。

(1)路径和路径长度:

在一棵树中,从一个结点往下可以达到的孩子或子孙结点之间的通路,称为路径。

通路中分支的数目称为路径长度。

若规定根结点的层数为1,则从根结点到第L层结点的路径长度为L-1。

  

(2)结点的权及带权路径长度  若将树中结点赋给一个有着某种含义的数值,则这个数值称为该结点的权。

结点的带权路径长度为:

从根结点到该结点之间的路径长度与该结点的权的乘积。

(3)树的带权路径长度  树的带权路径长度规定为所有叶子结点的带权路径长度之和,记为WPL。

哈夫曼树的构造

假设有n个权值,则构造出的哈夫曼树有n个叶子结点。

n个权值分别设为w1、w2、…、wn,则哈夫曼树的构造规则为:

(1)将w1、w2、…,wn看成是有n棵树的森林(每棵树仅有一个结点);

(2)在森林中选出两个根结点的权值最小的树合并,作为一棵新树的左、右子树,且新树的根结点权值为其左、右子树根结点权值之和;

(3)从森林中删除选取的两棵树,并将新树加入森林;

(4)重复

(2)、(3)步,直到森林中只剩一棵树为止,该树即为所求得的哈夫曼树。

哈夫曼编码(HuffmanCoding)是一种编码方式,哈夫曼编码是可变字长编码(VLC)的一种。

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

哈夫曼算法伪代码

1.数组huffTree初始化,所有元素结点的双亲、左右孩子都置为-1;

2.数组huffTree的前n个元素的权值置给定权值w[n];

3.进行n-1次合并

3.1在二叉树集合中选取两个权值最小的根结点,其下标分别为i1,i2;

3.2将二叉树i1、i2合并为一棵新的二叉树k;

哈夫曼压缩是个无损的压缩算法,一般用来压缩文本和程序文件。

哈夫曼压缩属于可变代码长度算法一族。

意思是个体符号(例如,文本文件中的字符)用一个特定长度的位序列替代。

因此,在文件中出现频率高的符号,使用短的位序列,而那些很少出现的符号,则用较长的位序列。

程序功能及输入输出要求:

控制台输入需编码的字符个数,分别输入字符符号以及权值后,进行哈夫曼编码,将编码结果输出到txt文件中。

编码结束后,可在控制台输入0,1字符串进行解码,若解码成功,输出解码结果。

(1):

编程软件MicrosoftVisualStudio2010

(2):

使用C++语言,自定义HuffmanCode类,在头文件HuffmanCode.h中。

如下如:

自定义类使用的字段,方法以及嵌套类型

图1:

HuffmanCode类的定义

(3):

HuffmanCode类的实现,在HuffmanCode.cpp文件中,如图

图2:

HuffmanCode类的实现

(4):

HuffmanCode主程序,在HuffmanCodeMain.cpp文件中,如图

图3:

主程序

详细设计

如图HuffmanCode类中的公有成员:

HuffmanCode();

主要进行初始化,申请所需内存空间,对字符命名及赋予权值;

HuffTree();

由初始化后的信息构造哈夫曼树;

Huff_Encode();

对字符进行哈夫曼编码;

Huff_Decode();

对二进制信息进行哈夫曼解码;

HuffCode(string&

CharacterCode);

哈夫曼解码算法,供成员Huff_Decode()调用;

Ele_Path(intn,boolchild);

供解码函数调用,返回下一个儿子结点所在下标;

~HuffmanCode();

析构函数,释放内存空间

HuffmanCode类中的私有成员:

structElement{

stringname;

intflag;

TEle_Weight;

intl_child,r_child,parent;

};

用于存放结点信息,即字符名称、标记、权值、左孩子、右孩子、双亲;

intNum;

字符个数;

Element*Elements;

一个指向Element结构体的指针;

string*Code;

所需解码的字符串指针;

调试与测试

n个字符进行哈夫曼编码,需2n-1个结点,在进行下标遍历时要注意,结点个数是2n-1但最后一个结点的下标是2n-2,否则地址出错,产生不可预测的结果;

执行解码时,由输入的0,1字符串判断下一个结点是左孩子还是右孩子,当浏览至叶子结点时,一定要把指针或者下表指向2n-1个结点(根节点)的位置,下表2n-2,否则会出错,导致解码失败;

执行n-1次合并时,参与过运算的结点一定要改变标记值,否则下次遍历会再次参与运算,导致结果错误。

程序源代码

(1)HuffmanCode.h

#include<

string>

usingstd:

:

string;

//HuffmanCode.h声明类HuffmanCode

#ifndefHuffmanCode_H

#defineHuffmanCode_H

template<

classT>

classHuffmanCode{

public:

HuffmanCode();

//构造函数,HuffTree初始化

voidHuffTree();

//构造哈夫曼树

voidHuff_Encode();

//哈夫曼编码函数

voidHuff_Decode();

//解码函数

voidHuffCode(string&

//解码算法

intEle_Path(intn,boolchild);

//供解码函数嵌套调用,返回下一个儿子结点下标

//n代表当前结点下标,child代表下一结点所在下标

~HuffmanCode();

//析构函数

private:

structElement{

//编码的字符

//标记

//权值

//左孩子,右孩子,双亲

intNum;

Element*Elements;

string*Code;

//存放计算出字符哈夫曼编码

};

#endif

(2)HuffmanCode.cpp

#include"

stdafx.h"

#include"

HuffmanCode.h"

//无参构造函数,确定字符数目n,并初始化2*n-1个结点

HuffmanCode<

T>

HuffmanCode(){

//输入一个大于2的整数

do{

cout<

<

"

Pleaseinputthenumber(above2)ofcharacters:

"

;

cin>

>

Num;

}while(Num<

2);

//新建2*Num-1个结点

Elements=newElement[2*Num-1];

for(inti=0;

i<

2*Num-1;

i++){

Elements[i].name="

Elements[i].Ele_Weight=0;

Elements[i].flag=0;

Elements[i].parent=-1;

Elements[i].l_child=-1;

Elements[i].r_child=-1;

}

Num;

PleaseinputthenameofNO."

i+1<

character'

sname:

Elements[i].name;

PleaseinputweightofNO."

character:

Elements[i].Ele_Weight;

//Textcout

cout<

Thedatastructurebeforcomputeis:

endl;

setw(4)<

Name"

setw(10)<

Weight"

<

setw(8)<

Flag"

Parent"

setw(15)<

Left_child"

Right_child"

Elements[i].flag;

Elements[i].parent;

Elements[i].l_child;

Elements[i].r_child;

}

template<

voidHuffmanCode<

HuffTree(){

inti=0,

MIN_1,MIN_2,//最小与次小元素下标

MIN_W1,MIN_W2;

//最小元素与次小元素的权值

for(i;

i<

Num-1;

i++){//n-1次合并

MIN_W1=MIN_W2=INT_MAX;

//climits中定义的常量值

MIN_1=MIN_2=0;

//下标0开始

//在森林中找两个权值最小的结点

for(intj=0;

j<

Num+i;

j++){//注意:

是Num+i不是Num+1

if(Elements[j].flag==0){//该点未加入HuffmanTree中

if(Elements[j].Ele_Weight<

MIN_W1){

MIN_W2=MIN_W1;

MIN_2=MIN_1;

MIN_W1=Elements[j].Ele_Weight;

MIN_1=j;

}

elseif(Elements[j].Ele_Weight<

MIN_W2){

MIN_W2=Elements[j].Ele_Weight;

MIN_2=j;

}

}

//确定两个最小结点的双亲

Elements[MIN_1].parent=Num+i;

Elements[MIN_2].parent=Num+i;

//标记已加入HuffTree中

Elements[MIN_1].flag=1;

Elements[MIN_2].flag=1;

Elements[Num+i].Ele_Weight=Elements[MIN_1].Ele_Weight+Elements[MIN_2].Ele_Weight;

Elements[Num+i].l_child=MIN_1;

Elements[Num+i].r_child=MIN_2;

Huff_Encode(){

//申请编码所需空间并初始化

Code=newstring[Num];

i++)

Code[i]="

//计算第i个结点的HuffMan编码

TCode_Weight=0;

intchild=0;

intparent=0;

i++){

Code_Weight=Elements[i].Ele_Weight;

child=i;

parent=Elements[i].parent;

//回溯

stringtemp;

while(parent!

=-1){

temp=(Elements[parent].l_child==child)?

0"

1"

Code[i].insert(0,temp);

child=parent;

parent=Elements[child].parent;

//输出结果

Thecharacter'

sCode"

Elements[i].name<

is"

Code[i]<

Huff_Decode(){

//求字符编码最长的长度

string:

size_typeMAX_Length=0;

Element"

'

ssizeis"

Code[i].size()<

if(Code[i].size()>

MAX_Length)

MAX_Length=Code[i].size();

Themaximumlengthofcodeis"

MAX_Length<

//求字符编码最小的长度

size_typeMIN_Length=MAX_Length;

if(Code[i].size()<

MIN_Length)

MIN_Length=Code[i].size();

Theminimumlengthofcodeis"

MIN_Length<

//

stringDecode="

do{//限制输入二进制代码长度

PleaseinputyourCode\n(ithavetolongerthancharacters'

maximumoflength):

\n"

//进行译码

HuffCode(Decode);

}while(cin>

Decode);

CharacterCode){

stringtemp="

intEle_Num=2*Num-2;

//注意:

元素个数是2*Num-1,但根结点下标是2*Num-2,否则参数传递时地址出错

for(string:

size_typeLength=0;

Length<

CharacterCode.size();

Length++){

if(CharacterCode[Length]=='

0'

){//该字符为‘0’

Ele_Num=Ele_Path(Ele_Num,false);

if(Elements[Ele_Num].l_child==-1&

&

Elements[Ele_Num].r_child==-1){

temp+=Elements[Ele_Num].name;

Ele_Num=2*Num-2;

//返回HuffmanTree的根结点

elseif(CharacterCode[Length]=='

1'

){//该字符为‘1’

Ele_Num=Ele_Path(Ele_Num,true);

Elements[Ele_Num].r_child==-1){

else{//输入编码中带有0,1以外的字符

cerr<

Thecodehavebeenmadewrong."

Ele_Num=0;

//这里Ele_Nun可以是任意一个!

=2*Num-2的值

break;

//译码输出

if(Ele_Num==2*Num-2)

Code"

CharacterCode<

temp<

else

cerr<

hasbeenwrong."

intHuffmanCode<

Ele_Path(intn,boolchild){

if(child==false){

returnElements[n].l_child;

else{

returnElements[n].r_child;

~HuffmanCode(){

delete[]Elements;

Elements=NULL;

delete[]Code;

Code=NULL;

(3)HuffmanCodeMain.cpp

//HuffmanCodeMain.cpp:

定义控制台应用程序的入口点。

//

#include<

iostream>

climits>

iomanip>

HuffmanCode.cpp"

cin;

cerr;

cout;

setw;

int_tmain(intargc,_TCHAR*argv[])

{

HuffmanCode<

int>

a;

a.HuffTree();

a.Huff_Encode();

a.Huff_Decode();

a.~HuffmanCode();

return0;

执行结果

(1)如图4,运行主程序,输入字符个数及名称后,指向Element结构体的指针指向一段具有2n-1个结构体的连续内存空间;

图4:

输入字符个数及名称

(2)数据在内存中结构如图5

图5:

初始化字符个数及名称后的数据结构

(3)随后生成哈夫曼树,在内存中结构如图6:

图6:

生成后的哈夫曼树

由哈夫曼树对字符进行编码并输出编码长度等信息:

图7:

生成编码解决方案

输出编码结果到HuffmanCode.txt文件中,如图8;

图8:

输出编码结果到HuffmanCode.txt文件中

(5):

解码,若输入无误,则输出解码结果(注:

Ctrl+Z结束解码)

图9:

哈夫曼解码

体会感想

经过这次数据结构课程设计,使我更加深刻体会了数据结构在实际应用中的作用,有效地组织好数据结构,可以有效地使系统高效率地执行。

而且通过开始的类的设计,程序的流程设计,以及后来类的具体实现,更使我深刻了解了更多C++语言的精妙之处,而且经历多次的调试,更加知道了程序的执行流程。

由于这次课程设计很早就得到了自己需要做的题目,因此有很长的时间准备,C++中最重要的指针部分也是我这次调试中问题最多的,但是最终都修改正确。

4、参考文献

1.王红梅.数据结构(C++版).清华大学出版社

2.谭浩强.C++程序设计.清华大学出版社

3.王红梅.数据结构学习辅导与实验指导.清华大学出版社

4.StanleyB.LippmanJoseeLa

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

当前位置:首页 > 解决方案 > 学习计划

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2