当前位置:文档之家› 哈夫曼编码课程设计

哈夫曼编码课程设计

湖南科技学院课程设计报告课程名称:数据结构课程设计课程设计题目:哈夫曼编码系:数学与计算科学系专业:信息与计算科学年级、班:信计0901姓名:郭如华学号:200905002145指导教师:牛志毅职称:讲师2011年12月目录1 问题描述 (3)2 基本要求 (3)3 测试数据 (3)4 算法思想 (3)5 模块划分 (3)6 数据结构 (3)7 源程序 (4)8 测试情况 (9)9 设计总结 (9)10参考资料 (9)1 问题描述设计一个哈夫曼编码系统,对文档中的报文进行编码,输出这段报文的哈夫曼编码,并且可以对输入的哈夫曼编码进行译码。

2 基本要求从文档中读取报文(如"what did you do that made you so happy")进行编码输出这段报文的哈夫曼编码。

3 测试数据what did you do that made you so happy4算法思想①:从文件中读取lei.txt并到数组z(保存所有字符的种类),读取data,txt存到数组ch(保存统计频数的一个样本)。

②:对数组z和数组ch进行比较统计出每个字符出现的频数,以频数代替权值,并把权值赋值到ht.weight的的数组中。

③:利用权值创建哈夫曼树。

④:利用哈夫曼树求的哈夫曼编码。

把lei.txt的数据赋值到hcd.ch中,把编好的哈夫曼编码赋值到hcd.code,则hcd这个数组就是一个哈夫曼编码的集合,hcd.ch 对应的下标就是这个字符所对应的哈夫曼编码。

⑤:输入要编码的字符,保存到ch数组,把ch数组的ch[j]元素逐个与hcd[i].ch 比较找出下标i,则hcd[i].code为ch[j]元素的哈夫曼编码。

⑥:输入要译码的哈夫曼编码lcd,逐个与hcd[i].code比较,找出下标i,则hcd[i].ch 为lcd所对应的字符。

5 模块划分①:void inithuffmantree(huffmantree ht);/*初始化哈夫曼树*/②:void tongji(huffmantree ht,huffmancode hcd,char *ch,char *z);/*统计权值*/③:void selectmin(huffmantree ht, int i, int *p1, int *p2);/*选择最小的权值*/④:void createhuffmantree(huffmantree ht) ;/*创建哈夫曼树*/⑤:void huffmancodes(huffmantree ht,huffmancode hcd,char *z) ;/*利用哈夫曼树求哈夫曼编码*/⑥:void bianma(huffmancode hcd);/*对输入的字符进行编码*/⑦:void yima(huffmancode hcd);/*对输入的哈夫曼编码进行译码*/6 数据结构typedef struct{int weight;int lchild,rchild,parent;}htnode;typedef htnode huffmantree[m+1];定义哈夫曼树的结构类型。

typedef struct{char ch;char code[10];} codenode;typedef codenode huffmancode[n+1];定义存储哈夫曼编码的类型。

7 源程序main.cpp#include <iostream>#include <conio.h>#include <stdlib.h>#include"huffman.h"#include<fstream>#include<string.h>using namespace std;int main(){char ch[200];/*用于存储样本*/char z[54];/*用于存储所有字符类别*/huffmantree ht;/*定义一个数组ht,用于存储哈夫曼树*/huffmancode hcd;/*定义一个数组hcd,用于存储哈夫曼编码*/inithuffmantree(ht);/*初始化哈夫曼树*/ifstream infile1("lei.txt");/*lei.txt文件保存了所有字符的总类*/if(!infile1){cout<<"错误:数据文件不能打开!";}for(int i=0; i<54; i++){infile1.get(z[i]);/*把lei.txt的数据读到数组z*/}ifstream infile2("data.txt");/*data.txt文件是统计频数的一个样本,以频数代替权值*/if(!infile2){cout<<"错误:数据文件不能打开!";}for(int i=0; i<200; i++){infile2.get(ch[i]);/*把data.txt数据读到数组ch*/}tongji(ht,ch,z);/*统计权值*/createhuffmantree(ht);/*创建哈夫曼树*/huffmancodes(ht,hcd,z);/*求哈夫曼编码*/bianma(hcd);/*对输入的字符求编码*/cout<<endl;yima(hcd);/*对输入的编码求译码*/}huffman.h#ifndef HUFFMAN_H_INCLUDED#define HUFFMAN_H_INCLUDED#define n 53#define m 2*n-1typedef struct{int weight;int lchild,rchild,parent;}htnode;typedef htnode huffmantree[m+1];/*定义数组存储哈夫曼树*/typedef struct{char ch;char code[10];} codenode;typedef codenode huffmancode[n+1];/*定义数组存储哈夫曼编码*/void inithuffmantree(huffmantree ht);/*初始化哈夫曼树*/void tongji(huffmantree ht,char *ch,char *z);/*统计权值*/void selectmin(huffmantree ht, int i, int *p1, int *p2);/*选择最小的权值*/ void createhuffmantree(huffmantree ht) ;/*创建哈夫曼树*/void huffmancodes(huffmantree ht,huffmancode hcd,char *z) ;/*利用哈夫曼树求哈夫曼编码*/void bianma(huffmancode hcd);/*对输入的字符进行编码*/void yima(huffmancode hcd);/*对输入的哈夫曼编码进行译码*/#endif // HUFFMAN_H_INCLUDEDhuffman.cpp#include<stdio.h>#include<stdlib.h>#include<string.h>#include<conio.h>#include<iostream>#include "huffman.h"using namespace std;void inithuffmantree(huffmantree ht)/*初始化哈夫曼树*/{for(int i=1; i<=m; i++){ht[i].weight=0;ht[i].lchild=0;ht[i].rchild=0;ht[i].parent=0;}}对传入函数的ht进行初始化。

void tongji(huffmantree ht,huffmancode hcd,char *ch,char *z)/*统计权值*/{int l;l=strlen(ch);for(int i=1; i<54; i++)for(int j=1; j<l; j++)if(z[i]==ch[j])ht[i].weight++;}数组ch是从文件data.txt中读取的数据,数组z是从lei.txt中读取的文件,把数组ch与数组z对比,统计每个字符出现的频数,存到ht.weight数组中。

void selectmin(huffmantree ht, int i, int *p1, int *p2)/*创建哈夫曼树*/{int j,min1,min2; /* min1,min2分别是最小权值和次小权值*/min1=min2=1;*p1=*p2=0;for(j=1; j<=i; j++){if(ht[j].parent==0)if(ht[j].weight<min1||min1==1){if(min1!=1){min2=min1;*p2=*p1;}min1=ht[j].weight;*p1=j;}else if(ht[j].weight<min2||min2==1){min2=ht[j].weight;*p2=j;}}}在ht[1..i]中选两个权值最小的根结点,其序号为*p1和*p2,*p1中放权值最小的根结点的序号,*p2中放权值次小的根结点的序号。

void createhuffmantree(huffmantree ht)/*利用哈夫曼树求哈夫曼编码*/{int i,p1,p2;inithuffmantree(ht);for(i=n+1; i<=m; i++){selectmin(ht,i-1,&p1,&p2);ht[p1].parent=ht[p2].parent=i;ht[i].lchild=p1;ht[i].rchild=p2;ht[i].weight=ht[p1].weight+ht[p2].weight;}}在ht[1..i]中选parents为0且weight最小的的两个结点。

其序号为p1,p2. void huffmancodes(huffmantree ht,huffmancode hcd,char *z)/*根据huffman树ht求huffman编码*/{int c,p,i;char cd[n+1];int start;cd[n]='\0';for(i=1; i<54; i++){hcd[i].ch=z[i];start=n;c=i;while((p=ht[c].parent)!=0){cd[--start]=(ht[p].lchild==c)?'0':'1';c=p;}strcpy(hcd[i].code,&cd[start]);}cout<<endl;}数组z是从lei.txt中读取的文件,并把数组lei的值逐个赋给hcd.ch,把编号的哈夫曼编码赋给hcd.code。

相关主题