哈夫曼编译码器.docx

上传人:b****9 文档编号:26268806 上传时间:2023-06-17 格式:DOCX 页数:54 大小:127.62KB
下载 相关 举报
哈夫曼编译码器.docx_第1页
第1页 / 共54页
哈夫曼编译码器.docx_第2页
第2页 / 共54页
哈夫曼编译码器.docx_第3页
第3页 / 共54页
哈夫曼编译码器.docx_第4页
第4页 / 共54页
哈夫曼编译码器.docx_第5页
第5页 / 共54页
点击查看更多>>
下载资源
资源描述

哈夫曼编译码器.docx

《哈夫曼编译码器.docx》由会员分享,可在线阅读,更多相关《哈夫曼编译码器.docx(54页珍藏版)》请在冰豆网上搜索。

哈夫曼编译码器.docx

哈夫曼编译码器

 

《数据结构--C++实现》

学院:

计算机学院

专业班级:

软件工程

课程设计报告

 

题目:

哈夫曼编/译码器

【问题描述】利用哈夫曼编码可以大大提高信道利用率,缩短信息传输时间,降低传输成本。

但是,这要求在发送端通过一个编码系统对传输数据预先编码,在接收端将传来的数据进行译码。

对于双工信道,每端都需要一个完整的编/译码器。

试为这样的通信端编写一个哈夫曼编/译码器。

1.需求分析

1.运行环境(软、硬件环境)

Visualstudio2008

2.程序实现的功能

初始化:

输入一串字符(正文),计算不同字符(包括空格)的数目以及每种字符出现的频率(以该种字符出现的次数作为其出现频率),根据权值建立哈夫曼树,输出每一种字符的哈夫曼编码。

编码:

利用求出的哈夫曼编码,对该正文(字符串)进行编码,并输出。

译码:

对于得到的一串编码,利用已求得的哈夫曼编码进行译码,将译出的正文输出。

输出哈夫曼树形态:

以树的形式输出哈夫曼树。

3.程序的输入

一串字符(英文)或短文(英文)

4.程序的输出

根据用户需求不同有相应的输出

5.测试数据

therearethreestudents

2.设计说明

1.算法设计的思想

建立链表类、栈类、队列类、哈夫曼结点类、哈夫曼树类,通过主函数调用的方法来实现程序的功能。

2.主要的数据结构说明

链表模板类:

template//模板链表类

classLinkList

{

private:

HuaffmanTreeNode*head;//链表的头结点

public:

TypeList[1000];

LinkList(void);

~LinkList(void);

HuaffmanTreeNode*GetHead();//

voidSetHead(HuaffmanTreeNode*h);//

voidInsert(HuaffmanTreeNode*p);//

HuaffmanTreeNode*IsTheSame(HuaffmanTreeNode*pa);//判断pa是否有相同的结点,如果有相同返回该结点,否则返回NULL

voidCreateList();//创建一个哈弗曼结点的链表

intGetLength();

HuaffmanTreeNode*Delete(HuaffmanTreeNode*p);//删除结点

HuaffmanTreeNode*Copy();//复制链表

boolCheckAllTure();//检查是否全部加入哈弗曼树

};

栈模板类:

template//模板栈类

classStack

{

private:

TData[MAX];

inttop;

public:

Stack();//构造函数

boolpush(Tnum);//进栈操作

Tpop();//出栈操作

TGet_top();//得到栈顶的元素

boolEmpty();//判断栈是否为空

boolFull();//判断栈是否已满

voidClear();//清空栈

};

队列模板类:

template//模板队列类

classQueue

{

private:

Tnum[MAX];//队列中的数据元素

intfront,rear;//队首,队尾的标志

public:

Queue(void);//构造函数

~Queue(void);//析构函数

voidEnQueue(Tp);//入队操作

TDeQueue();//出队操作

boolIsEmpty();//判断队列是否为空

boolIsFull();//判断队列是否已满

voidClear();//清空队列

};

哈夫曼结点模板类:

template//模板哈夫曼结点类

classHuaffmanTreeNode

{

private:

intKey;//该字符出现的次数;

TypeData;//输入的字符元素;

HuaffmanTreeNode*parent;//双亲结点指针;

HuaffmanTreeNode*lchild;//左孩子结点指针;

HuaffmanTreeNode*rchild;//右孩子结点指针;

intTag;//记录该结点是双亲的左右孩子,左孩子为,有孩子为;

HuaffmanTreeNode*next;//下一个结点,用于链表

boolFlag;//标记该结点是否已经计入哈弗曼树

public:

HuaffmanTreeNode(void);//默认构造函数;

HuaffmanTreeNode(intk,Typed,intt,HuaffmanTreeNode*p=NULL,HuaffmanTreeNode*l=NULL,HuaffmanTreeNode*r=NULL);//构造函数

~HuaffmanTreeNode(void);//默认析构函数;

intGetKey();//得到该结点在正文中出现的次数

voidSetKey(intkey);//设置关键字的次数

TypeGetData();//得到该结点对应的文字编码

voidSetData(Typedata);//设置结点的文字编码

HuaffmanTreeNode*GetParent();//得到该结点的双亲结点

voidSetParent(HuaffmanTreeNode*p);//设置双亲结点

HuaffmanTreeNode*GetLchild();//得到左孩子结点

voidSetLchild(HuaffmanTreeNode*p);//设置左孩子结点

HuaffmanTreeNode*GetRchild();//得到右孩子结点

voidSetRchild(HuaffmanTreeNode*p);//设置右孩子结点

intGetTag();//得到标记

voidSetTag(intt);//设置标记

HuaffmanTreeNode*GetNext();//得到下一个结点

voidSetNext(HuaffmanTreeNode*p);//设置下一个结点

boolGetFlag(){returnFlag;}

voidSetFlag(booltag){Flag=tag;}

};

哈夫曼树模板类:

template//模板哈夫曼树类

classHuaffmanTree

{

HuaffmanTreeNode*Root;//树根结点

Queuequ;//存放密码

public:

HuaffmanTree(void);

~HuaffmanTree(void);

voidSetRoot(HuaffmanTreeNode*p){this->Root=p;}

HuaffmanTreeNode*GetRoot(){returnRoot;}

HuaffmanTreeNode*Merge(HuaffmanTreeNode*pa,HuaffmanTreeNode*pb);//合并两个结点

voidCreateTree(LinkListL1);//创建哈夫曼树

int*GetCode(Typedata,LinkListL);//得到编码

voidCoding(LinkListL);//编码

voidDeCode(LinkListL);//译码函数

voidDisplay(HuaffmanTreeNode*p,intn);//遍历哈夫曼树

HuaffmanTreeNode*Find(Typedata,LinkListL);

voidGetCharFrenquency(LinkListL);//得到每种字符出现的次数

voidShowPriorText(LinkListL);

voidShowNodeBit(LinkListL);//输出每个结点的哈弗码编码

intGetHeight(HuaffmanTreeNode*p);//得到树的高度

};

3.程序的主要流程图

 

1

2

3

4

5

6

T

FF

 

4.程序的主要模块

#pragmaonce

#include"LinkList.h"

#include"Stack.h"

#include"Queue.h"

template//模板哈夫曼树类

classHuaffmanTree

{

HuaffmanTreeNode*Root;//树根结点

Queuequ;//存放密码

public:

HuaffmanTree(void);

~HuaffmanTree(void);

voidSetRoot(HuaffmanTreeNode*p){this->Root=p;}

HuaffmanTreeNode*GetRoot(){returnRoot;}

HuaffmanTreeNode*Merge(HuaffmanTreeNode*pa,HuaffmanTreeNode*pb);//合并两个结点

voidCreateTree(LinkListL1);//创建哈夫曼树

int*GetCode(Typedata,LinkListL);//得到编码

voidCoding(LinkListL);//编码

voidDeCode(LinkListL);//译码函数

voidDisplay(HuaffmanTreeNode*p,intn);//遍历哈夫曼树

HuaffmanTreeNode*Find(Typedata,LinkListL);

voidGetCharFrenquency(LinkListL);//得到每种字符出现的次数

voidShowPriorText(LinkListL);

voidShowNodeBit(LinkListL);//输出每个结点的哈弗码编码

intGetHeight(HuaffmanTreeNode*p);//得到树的高度

};

template

HuaffmanTree:

:

HuaffmanTree()

{

}

template

HuaffmanTree:

:

~HuaffmanTree()

{

this->Root=NULL;

}

template

HuaffmanTreeNode*HuaffmanTree:

:

Merge(HuaffmanTreeNode*pa,HuaffmanTreeNode*pb)

{

HuaffmanTreeNode*temp=newHuaffmanTreeNode();

if(pa->GetKey()GetKey())

{

temp->SetLchild(pa);

pa->SetTag(0);

temp->SetRchild(pb);

pb->SetTag

(1);

pa->SetFlag(true);

pb->SetFlag(true);

}

else

{

temp->SetLchild(pb);

pb->SetTag(0);

temp->SetRchild(pa);

pa->SetTag

(1);

pa->SetFlag(true);

pb->SetFlag(true);

}

temp->SetData('0');

temp->SetKey(pa->GetKey()+pb->GetKey());

pa->SetParent(temp);

pb->SetParent(temp);

returntemp;

}

 

template

voidHuaffmanTree:

:

CreateTree(LinkListL1)

{

HuaffmanTreeNode*pa,*pb;

pa=L1.GetHead()->GetNext();

pb=pa->GetNext();

while(pb)

{

HuaffmanTreeNode*temp=newHuaffmanTreeNode(pa->GetKey()+pb->GetKey(),'0',0);

pa->SetParent(temp);

pb->SetParent(temp);

if(pa->GetKey()>pb->GetKey())

{

temp->SetLchild(pb);

pb->SetTag(0);

pb->SetFlag(true);

temp->SetRchild(pa);

pa->SetTag

(1);

pa->SetFlag(true);

}

else

{

temp->SetLchild(pa);

pa->SetTag(0);

pa->SetFlag(true);

temp->SetRchild(pb);

pb->SetTag

(1);

pb->SetFlag(true);

}

L1.Insert(temp);

pa=pb->GetNext();

if(pa==NULL)

{

this->SetRoot(pb);

return;

}

pb=pa->GetNext();

if(!

pb)

{

this->SetRoot(pa);

return;

}

}

}

 

template

voidHuaffmanTree:

:

Display(HuaffmanTreeNode*p,intn)

{

if(p==NULL)

return;

this->Display(p->GetRchild(),n+1);

for(inti=0;i

cout<<'\t';

if(p->GetData()=='0')

cout<GetKey()<

else

{cout<GetKey()<<"("<GetData()<<')'<

this->Display(p->GetLchild(),n+1);

}

template

int*HuaffmanTree:

:

GetCode(Typedata,LinkListL)

{

Stacks;int*integer=newint[100];

HuaffmanTreeNode*current=L.GetHead()->GetNext();

while(current)

{

if(current->GetData()==data)

break;

current=current->GetNext();

}

if(current)

{

while(current->GetParent())

{

s.push(current->GetTag());

current=current->GetParent();

}

}

inti=0;

while(!

s.Empty())

{

qu.EnQueue(s.pop());

i++;

}

returninteger;

}

template

HuaffmanTreeNode*HuaffmanTree:

:

Find(Typedata,LinkListL)

{

HuaffmanTreeNode*current=L.GetHead()->GetNext();

while(current)

{

if(current->GetData()==data)

returncurrent;

current=current->GetNext();

}

returnNULL;

}

template

voidHuaffmanTree:

:

Coding(LinkListL)

{

qu.Clear();

inti=0;

while((L.List[i]<123&&L.List[i]>96)||L.List[i]==32)

{

GetCode(L.List[i],L);

i++;

}

}

 

template

voidHuaffmanTree:

:

DeCode(LinkListL)

{

inti=0;

while(!

qu.IsEmpty())

{

HuaffmanTreeNode*current=this->GetRoot();

while(current->GetData()=='0')

{

if(qu.DeQueue()==0)

current=current->GetLchild();

else

current=current->GetRchild();

}

cout<GetData();

}

}

 

template

voidHuaffmanTree:

:

GetCharFrenquency(LinkListL)

{

HuaffmanTreeNode*current=L.GetHead()->GetNext();

while(current)

{

if(current->GetData()!

='0')

{cout<GetData()<<""<GetKey()<

current=current->GetNext();

}

}

template

voidHuaffmanTree:

:

ShowPriorText(LinkListL)

{

inti=0;

while((L.List[i]<123&&L.List[i]>96)||L.List[i]==32)

{

cout<

i++;

}

}

template

voidHuaffmanTree:

:

ShowNodeBit(LinkListL)

{

HuaffmanTreeNode*current=L.GetHead()->GetNext();

while(current)

{

if(current->GetData()!

='0')

{cout<GetData()<<"";

GetCode(current->GetData(),L);

cout<

current=current->GetNext();

}

}

template

intHuaffmanTree:

:

GetHeight(HuaffmanTreeNode*p)

{

if(!

p)return0;

inthl,hr;

hl=GetHeight(p->GetLchild());

hr=GetHeight(p->GetRchild());

returnhl>hr?

++hl:

++hr;

}

3.上机结果及体会

1.完成情况

该程序可以统计每种字符出现的次数,每个字符的哈夫曼编码,编码后的密文以及哈夫曼树,也可以将编码后的密文进行译文。

2.程序的运行结果

输入数据

按1进行的操作

按2进行的操作

按3进行的操作

哈夫曼树以旋转90度输出。

其中数字表示权值,括号里的字符表示元素的。

按4进行的操作

按5进行的操作

按6进行的操作

按0结束

3.程序可以改进及扩充的功能设计实现假想

改进:

将哈夫曼树以正常的树的形式输出

扩充:

可以将汉字进行编码

4.收获及体会

更加深入的理解数据的存储结构,能更好的利用数据的存储来增加空间的利用率.通过自己动手编写,将所学内容运用到实际中。

4.参考文献

《数据结构--C++实现》(修订版)缪淮扣、顾训穰、沈俊  编著

 

附录(源程序):

//主函数

#include"HuaffmanTree.h"

#include

usingnamespacestd;

intchoice;

voidMune(void)

{

cout<

cout<<"1.显示字符的种类及每种字符出现的次数。

"<

cout<<"2.输出原来的文本。

"<

cout<<"3.输出Huffman树。

"<

cout<<"4.得到每个结点的Huffman编码。

"<

cout<<"5.输出整个文章的Huffman密文。

"<

cout<<"6

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

当前位置:首页 > PPT模板 > 简洁抽象

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

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