哈夫曼编解码 完整c程序代码

哈夫曼编解码 完整c程序代码
哈夫曼编解码 完整c程序代码

哈夫曼编解码完整c程序代码

Huffman 编码进行通信可以大大提高信道的利用率,缩短信息传输时间,降低传输成本。但是,这要求在发送端通过一个编码系统对待传数据进行预先编码,在接收端进行解码。对于双工信道(即可以双向传输信息的信道),每端都需要一个完整的编/解码系统。

2)要求:

一个完整的huffman编解码系统应该具有以下功能:

初始化(Initialization)。从终端读入字符集大小n,以及n个字符和n个权值,建立Huffman 树,并将它存入hfmTree 中。

编码(Encoding)。利用已经建好的Huffman树(如果不在内存,则应从文件hfmTree中读取),对文件ToBeTran中的正文进行编码,然后将结果存入文件hfmTree中读取),对文件ToBeTran中的正文进行编码,然后将结果存入文件CodeFile中。

解码(Decoding)。利用已经建立好的Huffman树将文件CodeFile中的代码进行解码,结果存入TextFile中。

打印代码文件(Print)。将文件CodeFile以紧凑的格式显示在终端上,每行50 个代码。同时将此字符形式的编码文件写入文件CodePrint中。

打印Huffman树(Tree Printing)。将已经在内存中的Huffman树以直观的形式(树或者凹入的形式)显示在终端上,同时将此字符形式的Huffman 树写入文件TreePrint中。3) 测试数据: 用下表给出的字符集和频度的实际统计数据建立Huffman树,并对以下报文进行编码和译码:“THIS PROGRAM IS MY FAVORITE”。字符 A B C D E F G H I J K L M 频度1866413223210321154757153220 字符 N O P Q R S T U V W X Y Z 频度5763151485180238181161 完整代码如下:

#include

h>#include#include#define N100int

*w;char *c,stack[N],code[N][N];int s1,s2;typedef struct HuffmanTree{int weight;int parent;int lchild;int rchild;}HuffmanTree,*Huff;void menu(void); void

Select(struct HuffmanTree HT[],int i); void

HuffmanTree(Huff &HT,int *w,int n);void visite(Huff

HT,int i,int flag,int rear);void translatef(char

*scource,char *save,int n);bool uncodef(FILE *fp1,FILE

*fp2,Huff HT,int n);int inputHuff();void screanio(int n);void fileio(int n);int initHuff();void Print_tree(int n,Huff HT);void Convert_tree(Huff HT,unsigned char

T[100][100],int tt[100][100],int s,int *i,int j);void decoding(int n);void coding(int n);void main(){int

n=0;menu();Huff HT;char state;

do{std::cout<<"input:\n";std::cin>>state;fflush(stdin); //读取状态

switch(state){ caseI:n=inputHuff();HuffmanTree(HT,w,n);st d::cout<<"\nHuffmanTree 初始化完毕\n";break;

caseC:coding(n);break; caseD:decoding(n);break;

caseP:Print_tree(n,HT);break;

caseQ:break;}}while(state!=Q);}void menu()

//显示菜单函数

{std::cout<<"===========HuffmanCoding===========\n"; std::cout<<"input \t\t do\n";std::cout<<"I

\t\tInit_HUffTree\n"; //初始化huffmantreestd::cout<<"C \t\tCoding\n"; //对ToBeTran、txt文件中的字符进行编码到CodeFile、txt中std::cout<<"D \t\tUnCoding\n"; //对CodeFile、txt中的01序列进行解码到TextFile、

txtstd::cout<<"P \t\tPrintTree\n"; //打印哈夫曼树

std::cout<<"Q \t\tquit\n";std::cout<<"请初始化哈夫曼树再执行后面的操作\n";}int inputHuff()

//输入各个字母及其权值{int i=1,n=0;int ww[28];char cc[28];while(1){std::cout<<"input the letter(input # to stop):";cc[i]=std::cin、

get();fflush(stdin);if(cc[i]==#)break;std::cout<<"input

the

weight:";std::cin>>ww[i];fflush(stdin);n++;i++;}w=(int *)malloc(sizeof(int)*(n+1));c=(char

*)malloc(sizeof(char)*(n+1));for(i=0;i

*w,int n)

//初始化哈夫曼树{int m,i;m=n*2-1;HT=(struct HuffmanTree *)malloc(sizeof(struct

HuffmanTree)*(m+1));HT[0]、lchild=0;HT[0]、

parent=0;HT[0]、rchild=0;HT[0]、

weight=0;for(i=1;i

weight=i<=n?w[i]:0;HT[i]、lchild=HT[i]、rchild=HT[i]、parent=0;}for(i=n+1;i<=m;i++){ Select(HT,i);HT[i]、

lchild=s1;HT[i]、rchild=s2;HT[i]、weight=HT[s1]、

weight+HT[s2]、weight;HT[s1]、parent=HT[s2]、

parent=i;}}void Select(struct HuffmanTree HT[],int i) //在HT[1、、i-1]中选择parent为0且weight为最小的两个结点{ int j;for(j=1;j

==0){s1=j;s2=j;goto flag;}}flag:

for(j=s1+1;j=HT[j]、weight){s2=s1;s1=j;}if(HT[s2]、

weight>HT[j]、weight&&j!=s1)s2=j;if(s1==s2)s2=j;}}}void Print_tree(int n,Huff HT)

//以凹入法的形式打印树{ unsigned char T[100][100];

int tt[100][100]; int i,j,m=0; FILE *fp;

Convert_tree(HT,T,tt,0,&m,2*n-1); //将内存中的赫夫曼树转

换成凹凸表形式的树,存于数组T中

if((fp=fopen("treeprint、txt","wb+"))==NULL)

printf("Open file treeprint、txt error!\n");

printf("\n以凹凸表形式打印已建好的赫夫曼树:\n");

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

{ for (j=0;T[i][j]!=0;j++)

{ if(T[i][j]== )

{printf(" ");fputc(T[i][j],fp);} else

{printf("%d",tt[i][j]);fprintf(fp,"%d\n\n\n",tt[i][j]);} } printf("\n"); } fclose(fp); printf("\n此字符形式的哈夫曼

树已写入文件treeprint、txt中、\n\n"); printf("\n文件treeprint、txt的打开方式要为写字板,若打开方式为记事本,

则无法显示凹凸表的形式\n"); } void Convert_tree(Huff

HT,unsigned char T[100][100],int tt[100][100],int s,int

*i,int j)

//将内存中的赫夫曼树转换成凹凸表形式的树,存于数组T

中{ int k,l; l=++(*i); for(k=0;k

T[l][k]= ; T[l][k]=#; tt[l][k]=HT[j]、weight;

if(HT[j]、lchild)

Convert_tree(HT,T,tt,s+1,i,HT[j]、lchild); if(HT[j]、rchild)

Convert_tree(HT,T,tt,s+1,i,HT[j]、rchild);

T[l][++k]=\0; } void coding(int n)

//对文件ToBeTran、txt编码到CodeFile、txt{ FILE

*fp1;Huff HT;HuffmanTree(HT,w,n);visite(HT,2*n-

1,2,0);fflush(stdin);translatef("ToBeTran、txt","CodeFile、txt",n);fp1=fopen("CodeFile、txt","r");printf("\n编码已写入文件treeprint、txt中、

\n");fclose(fp1);}void decoding(int n)

//对CodeFile、txt中的01序列进行解码到TextFile、

txt{FILE *fp1,*fp2;Huff

HT;HuffmanTree(HT,w,n);fp1=fopen("CodeFile、txt","r");fp2=fopen("TextFile、

txt","w");while(uncodef(fp1,fp2,HT,2*n-

1));printf("\n");printf("\n解码已写入文件TextFile、txt 中、\n");fclose(fp1);fclose(fp2);}void visite(Huff HT,int i,int flag,int rear)//通过递归调用visite()函数,得到各个字母的编码,存储于全局变量code[][]中{int

j=0,k=0;if(flag==0){ stack[rear]=0;rear++;}else

if(flag==1){stack[rear]=1;rear++;}if(HT[i]、

lchild==0){for(j=0;j

lchild,0,rear);visite(HT,HT[i]、

rchild,1,rear);k=rear;for(j=0;j

*scource,char *save,int n)//读取文件中的字母序列,并根据code[][]将其转换成01序列输出{FILE *fp1,*fp2;char p= ;int i=0,j=0,k=0;fp1=fopen(scource,"r");fp2=fopen(save,"w");p= fgetc(fp1);printf("\n得到的编码

为:\n");while(p!=EOF){for(i=0;i<=n;i++){if(c[i]==p){for(j =0;j=50){k=0;putchar(\n);}}}}p=fgetc(fp1 );}fclose(fp1);fclose(fp2);}bool uncodef(FILE *fp1,FILE *fp2,Huff HT,int n)//通过对树的访问,把文件中01序列转换成一个字母输出。本函数需循环调用,当读到\n时返回

false{char

p= ;if(!fp1||!fp2){printf("error");exit(0);}if(HT[n]、lchild==0){fputc(c[n],fp2);return

true;}else{p=fgetc(fp1);if(p==EOF){return

false;}}if(p==0){uncodef(fp1,fp2,HT,HT[n]、lchild);}else if(p==1){uncodef(fp1,fp2,HT,HT[n]、rchild);}return

true;}/*以下在初始化哈夫曼树时复制粘贴可用,注意第一个为空格,weight为186,复制粘贴时要包括它、输入以#号结束

186A64B13C22D32E103F21G15H47I57J1K5L32M20N57O63P15Q1R48S5 1T80U23V8W18X1Y16Z1#*/

哈夫曼树的编码与译码

目录 一、摘要 (3) 二、题目 (3) 三、实验目的 (3) 四、实验原理 (3) 五、需求分析 (4) 5.1实验要求 (4) 5.2实验内容 (4) 六、概要设计 (4) 6.1所实现的功能函数 (4) 6.2主函数 (5) 6.3 系统结构图 (6) 七、详细设计和编码 (6) 八、运行结果 (12) 九、总结 (15) 9.1调试分析 (15) 9.2 心得体会 (15) 参考文献 (16)

一、摘要 二、题目 哈夫曼树的编码与译码 三、实验目的 (1)熟悉对哈夫曼的应用以及构造方法,熟悉对树的构造方式的应用; (2)进一步掌握哈夫曼树的含义; (3)掌握哈夫曼树的结构特征,以及各种存储结构的特点以及使用范围; (4)熟练掌握哈夫曼树的建立和哈夫曼编码方法; (5)提高分析问题、解决问题的能力,进一步巩固数据结构各种原理与方法; (6)掌握一种计算机语言,可以进行数据算法的设计。 四、实验原理 哈夫曼(Huffman)编码属于长度可变的编码类,是哈夫曼在1952年提出的一种编码方法,即从下到上的编码方法。同其他码词长度一样,可区别的不同码词的生成是基于不同符号出现的不同概率。生成哈夫曼编码算法基于一种称为“编码树”(coding tree)的技术。算法步骤如下: (1)初始化,根据富豪概率的大小按由大到小顺序对符号进行排序; (2)把概率最小的两个符号组成一个新符号(节点),即新符号的概率等于这两个符号概率之和; (3)重复第(2)步,直到形成一个符号为止(树),其概率最后等于1; (4)从编码树的根开始回溯到原始的符号,并将每一下分支赋值1,上分支赋值0; 译码的过程是分解电文中字符串,从根出发,按字符“0”或者“1”确定找做孩 子或右孩子,直至叶子节点,便求得该子串相应的字符。

哈夫曼树编码译码实验报告(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) 编码文件的译码。

哈夫曼树的编码和译码

#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; }

霍夫曼编码

霍夫曼编码 霍夫曼编码(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) 该字符串的平均码长

赫夫曼树的编码译码

#include #include #include typedef struct{ int weight; int lchild,rchild,parent; }Htnode,*HuffmanTree; //哈弗曼树节点类型,动态分配数组存储哈弗曼树typedef char * * Huffmancode; //动态分配数组存储哈弗曼编码表 void bianma(Huffmancode ch,int n); //编码 void yima(Htnode *HT, int n); //译码 int createtree(Htnode *&HT, Huffmancode &HC,int *weight,int n); //构建哈弗曼树void select(Htnode *HT,int n,int *s1,int *s2); //求节点中两个最小数 /*----------main 函数----------*/ int main (void) { Htnode *HT; int n=4,a; //叶子节点4个 int weight[5]={18,7,5,2,4}; //weight[0]为权值之和 char ch[4]={'A','B','C','D'},c; char **HC; createtree(HT, HC,weight, n); while(a!=0){ //a=0时退出,so是按0键退出,或者改成a!=3 printf("***编码请按1,译码请按2,退出请按0***"); printf("请输入您的选择:\n"); scanf("%d%c",&a,&c); switch(a){ case 1: bianma(HC,n); break; case 2: yima(HT,2*n); break; case 0: break; default:printf("输入错误!");break; } } return 0; }

(在VC++上调试通过)哈夫曼树编码上机实验

//注意:在输入n个权值时,每输入一个权值都要按一个回车键 #include"iostream" #include"stdlib.h" #include"stdio.h" #include"malloc.h" #include"string.h" using namespace std; #define UNIT_MAX 65535 typedef struct TNode { int parent; unsigned int weight; unsigned int lchild; unsigned int rchild; } *HuffmanTree, HTNode; typedef char **HuffmanCode; int select(HuffmanTree t, int i)//返回根节点中权值最小的树的根节点的序号函数select()调用{ int j; int find=0; int k = UNIT_MAX;//取K为不小于可能的值 for (j = 1; j < i; j++) //在t数组的前i-1个数组元素中寻找一个parent值为0且权值最小的if ((int)t[j].weight < k && t[j].parent == 0) { k = t[j].weight; find=j; } t[find].parent = 1; return find; } char** HuffmanCoding(HTNode HT[], char* HC[], int w[], int n) { //w存放n个字符的权值的一维数组,n为叶子个数;构造哈夫曼树HT;HC数组用以存放求得的n个字符的编码 int m, i, s1, s2, start; int c, f; HuffmanTree p; char* cd; m = 2 * n - 1; //n即为叶子数n0,由二叉树性质,n0=n2+1,故树中结点数为*n-1 for (i = 1, p = HT + 1; i <= n; ++i, ++p, ++w) {//n个叶子结点赋初值,n个叶子最初为n个根结点,p指向HT[1],HT[0]不用(*p).weight = *w; (*p).parent = 0; (*p).lchild = 0; (*p).rchild = 0; } for (i=n+1; i <= m; i++, p++) //n-1个附加的父亲结点赋初值 { (*p).weight = 0; (*p).parent = 0; (*p).lchild = 0; (*p).rchild = 0;

哈夫曼树编码

哈夫曼树编码 #include #include #define MAX_NODE 1024 #define MAX_WEIGHT 4096 typedef struct HaffmanTreeNode { char ch, code[15]; int weight; int parent, lchild, rchild; } HTNode, *HaTree; typedef struct { HTNode arr[MAX_NODE]; int total; } HTree; /* 统计字符出现的频率 */ int statistic_char(char *text, HTree *t){ int i, j; int text_len = strlen(text); t->total = 0; for (i=0; itotal; j++) if (t->arr[j].ch == text[i]){ t->arr[j].weight ++; break;

} if (j==t->total) { t->arr[t->total].ch = text[i]; t->arr[t->total].weight = 1; t->total ++; } } printf("char frequence\n"); for (i=0; itotal; i++) printf("'%c' %d\n", t->arr[i].ch, t->arr[i].weight); printf("\n"); return t->total; } int create_htree(HTree *t) { int i; int total_node = t->total * 2 - 1; int min1, min2; /* 权最小的两个结点 */ int min1_i, min2_i; /* 权最小结点对 应的编号 */ int leaves = t->total; for (i=0; iarr[i].parent = -1;

哈夫曼树建立、哈夫曼编码算法的实现

#include /*2009.10.25白鹿原*/ #include /*哈夫曼树建立、哈夫曼编码算法的实现*/ #include typedef char* HuffmanCode;/*动态分配数组,存储哈夫曼编码*/ typedef struct { unsigned int weight ; /* 用来存放各个结点的权值*/ unsigned int parent, LChild,RChild ; /*指向双亲、孩子结点的指针*/ }HTNode, * HuffmanTree; /*动态分配数组,存储哈夫曼树*/ void select(HuffmanTree *ht,int n, int *s1, int *s2) { int i; int min; for(i=1; i<=n; i++) { if((*ht)[i].parent == 0) { min = i; i = n+1; } } for(i=1; i<=n; i++) { if((*ht)[i].parent == 0) { if((*ht)[i].weight < (*ht)[min].weight) min = i; } } *s1 = min; for(i=1; i<=n; i++) { if((*ht)[i].parent == 0 && i!=(*s1)) { min = i; i = n+1; } } for(i=1; i<=n; i++) { if((*ht)[i].parent == 0 && i!=(*s1)) {

if((*ht)[i].weight < (*ht)[min].weight) min = i; } } *s2 = min; } void CrtHuffmanTree(HuffmanTree *ht , int *w, int n) { /* w存放已知的n个权值,构造哈夫曼树ht */ int m,i; int s1,s2; m=2*n-1; *ht=(HuffmanTree)malloc((m+1)*sizeof(HTNode)); /*0号单元未使用*/ for(i=1;i<=n;i++) {/*1-n号放叶子结点,初始化*/ (*ht)[i].weight = w[i]; (*ht)[i].LChild = 0; (*ht)[i].parent = 0; (*ht)[i].RChild = 0; } for(i=n+1;i<=m;i++) { (*ht)[i].weight = 0; (*ht)[i].LChild = 0; (*ht)[i].parent = 0; (*ht)[i].RChild = 0; } /*非叶子结点初始化*/ /* ------------初始化完毕!对应算法步骤1---------*/ for(i=n+1;i<=m;i++) /*创建非叶子结点,建哈夫曼树*/ { /*在(*ht)[1]~(*ht)[i-1]的范围内选择两个parent为0且weight最小的结点,其序号分别赋值给s1、s2返回*/ select(ht,i-1,&s1,&s2); (*ht)[s1].parent=i; (*ht)[s2].parent=i; (*ht)[i].LChild=s1; (*ht)[i].RChild=s2; (*ht)[i].weight=(*ht)[s1].weight+(*ht)[s2].weight; } }/*哈夫曼树建立完毕*/ void outputHuffman(HuffmanTree HT, int m) { if(m!=0) {

哈夫曼树及编码综合实验报告

《用哈夫曼编码实现文件压缩》 实验报告 课程名称数据结构B 实验学期 2017 至 2018 学年第一学期学生所在院部计算机学院 年级 2016 专业班级信管B162 学生姓名学号 成绩评定: 1、工作量: A(),B(),C(),D(),F( ) 2、难易度:A(),B(),C(),D(),F( ) 3、答辩情况: 基本操作:A(),B(),C(),D(),F( ) 代码理解:A(),B(),C(),D(),F( ) 4、报告规范度:A(),B(),C(),D(),F( ) 5、学习态度:A(),B(),C(),D(),F( )总评成绩:_________________________________ 指导教师: 兰芸

用哈夫曼编码实现文件压缩 1、了解文件的概念。 2、掌握线性链表的插入、删除等算法。 3、掌握Huffman树的概念及构造方法。 4、掌握二叉树的存储结构及遍历算法。 5、利用Huffman树及Huffman编码,掌握实现文件压缩的一般原理。 微型计算机、Windows 7操作系统、Visual C++6.0软件 输入的字符创建Huffman树,并输出各字符对应的哈夫曼编码。 五.系统设计 输入字符的个数和各个字符以及权值,将每个字符的出现频率作为叶子结点构建Huffman树,规定哈夫曼树的左分支为0,右分支为1,则从根结点到每个叶子结点所经过的分支对应的0和1组成的序列便为该结点对应字符的哈夫曼编码。 流程图如下 1.输入哈夫曼字数及相应权值

相应代码 int main() { HuffmanTree HTree; HuffmanCode HCode; int *w, i; int n,wei; //编码个数及权值 printf("请输入需要哈夫曼编码的字符个数:"); scanf("%d",&n); w=(int*)malloc((n+1)*sizeof(int)); for(i=1; i<=n;i++) { printf("请输入第%d字符的权值:",i); fflush(stdin); scanf("%d",&wei); w[i]=wei; } HuffmanCoding(&HTree,&HCode,w,n); return 1; } 2.输出HT初态(每个字符的权值)

实验四 哈夫曼树与哈夫曼编码报告

软件学院 实验名称:哈夫曼树与哈夫曼编码 专业:软件工程 班级:卓越121班 学号: 201207092235 学生姓名:刘焕超 指导教师:高艳霞 2014年06 月02 日

一、实验目的: 1、熟悉并掌握栈的创建、入栈和出栈等基本用法并能运用栈完成一些特定的任 务。 2、将理论知识与实践相结合,提高自己的实际动手能力。 3、通过实践来及时发现自己的缺点与不足,以便为接下来更加有效的学习做铺 垫。 4、通过对上机来检测自己所学知识的程度,为以后更好的掌握知识改进学习方 法。 二、实验要求 1.预习C 语言中结构体的定义与基本操作方法。 2.对单链表的每个基本操作用单独的函数实现。 3.编写完整程序完成下面的实验内容并上机运行。 4.整理并上交实验报告. [问题描述] 已知n个字符在原文中出现的频率,求它们的哈夫曼编码。 [基本要求] 1. 初始化:从键盘读入n个字符,以及它们的权值,建立Huffman 树。(具体算法可参见教材P147的算法6.12) 2. 编码:根据建立的Huffman树,求每个字符的Huffman编码。 对给定的待编码字符序列进行编码。 [选作内容] 1. 译码:利用已经建立好的Huffman树,对上面的编码结果译码。 译码的过程是分解电文中的字符串,从根结点出发,按字符’0’和’1’确定找左孩子或右孩子,直至叶结点,便求得该子串相应的字符。 4. 打印 Huffman树。 [测试数据] 利用教材P.148 例6-2中的数据调试程序。可设8种符号分别为A,B,C,D,E,F,G,H。编/译码序列为“CFBABBFHGH”(也可自己设定数据进行测试)。 四、算法设计思想及步骤:

哈夫曼编码的方法

1.哈夫曼编码的方法 编码过程如下: (1) 将信源符号按概率递减顺序排列; (2) 把两个最小的概率加起来, 作为新符号的概率; (3) 重复步骤(1) 、(2), 直到概率和达到1 为止; (4) 在每次合并消息时,将被合并的消息赋以1和0或0和1; (5) 寻找从每个信源符号到概率为1处的路径,记录下路径上的1和0; (6) 对每个符号写出"1"、"0"序列(从码数的根到终节点)。 2.哈夫曼编码的特点 ①哈夫曼方法构造出来的码不是唯一的。 原因 ·在给两个分支赋值时, 可以是左支( 或上支) 为0, 也可以是右支( 或下支) 为0, 造成编码的不唯一。 ·当两个消息的概率相等时, 谁前谁后也是随机的, 构造出来的码字就不是唯一的。 ②哈夫曼编码码字字长参差不齐, 因此硬件实现起来不大方便。 ③哈夫曼编码对不同的信源的编码效率是不同的。 ·当信源概率是2 的负幂时, 哈夫曼码的编码效率达到100%; ·当信源概率相等时, 其编码效率最低。 ·只有在概率分布很不均匀时, 哈夫曼编码才会收到显著的效果, 而在信源分布均匀的情况下, 一般不使用哈夫曼编码。 ④对信源进行哈夫曼编码后, 形成了一个哈夫曼编码表。解码时, 必须参照这一哈夫编码表才能正确译码。 ·在信源的存储与传输过程中必须首先存储或传输这一哈夫曼编码表在实际计算压缩效果时, 必须考虑哈夫曼编码表占有的比特数。在某些应用场合, 信源概率服从于某一分布或存在一定规律

使用缺省的哈夫曼编码表有

解:为了进行哈夫曼编码, 先把这组数据由大到小排列, 再按上方法处理 (1)将信源符号按概率递减顺序排列。 (2)首先将概率最小的两个符号的概率相加,合成一个新的数值。 (3)把合成的数值看成是一个新的组合符号概率,重复上述操作,直到剩下最后两个符号。 5.4.2 Shannon-Famo编码 Shannon-Famo(S-F) 编码方法与Huffman 的编码方法略有区别, 但有时也能编 出最佳码。 1.S-F码主要准则 符合即时码条件; 在码字中,1 和0 是独立的, 而且是( 或差不多是)等概率的。 这样的准则一方面能保证无需用间隔区分码字,同时又保证每一位码字几乎有 1位的信息量。 2.S-F码的编码过程 信源符号按概率递减顺序排列; 把符号集分成两个子集, 每个子集的概率和相等或近似相等;

哈夫曼树编码

哈夫曼树编码/译码系统 【实验内容及要求】 (1) 从终端读入字符集大小为n(即字符的个数),逐一输入n个字符和相应的n个权值(即字符出现的频度),建立哈夫曼树,将它存于文件hfmtree 中。并将建立好的哈夫曼树以树或凹入法形式输出;对每个字符进行编码并且输出。 (2) 利用已建好的哈夫曼编码文件hfmtree ,对键盘输入的正文进行译码。输出字符正文,再输出该文的二进制码。 #include #include #include #include #define num 27 //字母数 #define nod 51 //总的树结点的个数 #define len 15 //编码最大长度 class Node { public: char data; int weight; int parent; int lchild; int rchild; }; int main() { ofstream out("test6.txt"); char ch[27]; for(int nn=0;nn<27;nn++) { ch[nn]=65+nn; out<

int static hc[num][len]; //用于存储编码 int m,n; //初始化数组 for(i=0;itwo&&nodes[j].weight<=one) { one=nodes[j].weight; a=j; } } }//for语句得到parent=-1(即没父结点)且weight最小的两个结点nodes[a].parent=i;

哈夫曼树 哈夫曼编码(先序遍历方法)

#include #include typedef struct Tree { int weight; int left; int right; int parent; }*tree; void CreateHuffman(int n) { int i; int m1,m2,x1,x2; tree Huffman[100]; for(i=0;i< 2*n-1;i++) { Huffman[i] = (tree) malloc(sizeof(struct Tree)); } for(i=0;iweight); } for(i=0;i<2*n-1;i++) { Huffman[i]->parent = -1; Huffman[i]->left = -1; Huffman[i]->right = -1; } int j; for(i=0;i

if( Huffman[j]->weight < m1 && Huffman[j]->parent == -1) { m1 = Huffman[j]->weight ; x1 = j; } } for(j=0;jweight < m2 && Huffman[j]->parent == -1 && x1 != j) { m2 = Huffman[j]->weight ; x2 = j; } } Huffman[x1]->parent = n+i; Huffman[x2]->parent = n+i; Huffman[n+i]->weight =Huffman[x1]->weight + Huffman[x2]->weight ; Huffman[n+i]->left =x1; Huffman[n+i]->right =x2; } for(i=0;i<2*n-1;i++) { printf("%d,", Huffman[i]->weight); } printf("\n"); for(i=0;i<2*n-1;i++) { printf("%d的左结点的下标为%d,右结点的下标为%d\n",Huffman[i]->weight,Huffman[i]->left,Huffman[i]->right); } char s[100]; int x; i--; x = i; int k; k=0; int rs[100];int ls[100]; i=1; tree q[100]; int sum=0;

Huffman树与Huffman树编码算法

实验七 Huffman树与Huffman树编码算法实验(4学时)* 数学与软件科学学院实验报告 学期:2011至2012第 1 学期 2012年 5 月 12 日 课程名称:数据结构专业:信息与计算科学 班级 2010级5班实验编号:实验七 实验项目Huffman树与Huffman树编码算法实验指导教师 ** 姓名:** 学号:201** 实验成绩: 实验名称:Huffman树与Huffman树编码算法实验 实验目的: 掌握Huffman树的编码方法和算法实现。 实验内容:(类C算法的程序实现) (1) 建立Huffman树编码的表示结构,对给定输入信息集合进行Huffman编码,输出编码结果(必做) (2) 利用Huffman编码算法实现给定信息串的编码结果(必做) 实验准备: 1) 计算机设备;2) 程序调试环境的准备,如TC环境;3) 实验内容的算法分析与代码设计与分析准备。 实验步骤: (1)算法思想 对于随机输入的一串字符 <1>统计字符串中各类字符。 <2>统计各类字符在字符串中的个数 <3>创建haffman树。 <4>字符进行huffman编码。 <5>输出字符串的haffman编码。 (2)设计算法的数据结构 1) /*数据结构*/ typedef struct HTTree{ DataType weight;/*字符的个数*/ int flag;/*标记元素*/ char name;/*字符名字*/ int parents,leftChild,rightChild;/*父亲结点、子节点*/ }HTNode,*HuffmanTree; (3)算法基本操作和描述 1)统计字符串中各类字符,统计各类字符在字符串中的个数。 *函数*/ int IpChar(char *a,int **a1, char *b)

三进制霍夫曼编码

精心整理题目:将霍夫曼编码推广至三进制编码,并证明它能产生最优编码。 ※将霍夫曼编码推广至三进制编码 设一个数据文件包含Q个字符:A1,A2,……,Aq,每个字符出现的频度对应为P:P1,P2,……,Pq。 1.将字符按频度从大到小顺序排列,记此时的排列为排列1。 2.用一个新的符号(设为S1)代替排列1中频度值最小的Q-2k(k为(Q-1)/2取整)个字符,并记其频度值为排列1中最小的Q-2k个频度值相加,再重新按频度从大到小顺序排列字符,记为排列2。(注:若Q-2k=0,则取其值为2,若Q-2k=1,则取其值为 3.) 3.对排列2重复上述步骤2,直至最后剩下3个概率值。 4.从最后一个排列开始编码,根据3个概率大小,分别赋予与3个字符对应的值:0、1、2,如此得到最后一个排列3个频度的一位编码。 5.此时的3个频度中有一个频度是由前一个排列的3个相加而来,这3个频度就取它的一位编码后面再延长一位编码,得到二位编码,其它不变。 6.如此一直往前,直到排列1所有的频度值都被编码为止。 举例说明如下(假设Q=9): 字符A1 A2 A3 A4 A5 A6 A7 A8 A9 频度0.22 0.18 0.15 0.13 0.10 0.07 0.07 0.05 0.03 字符频度编码频度编码频度编码频度编码 A1 0.22 2 0.22 2 0.30 1 0.480 A2 0.18 00 0.18 00 0.22 2 0.30 1 A3 0.15 02 0.1501 0.18 00 0.22 2 A4 0.13 10 0.15 02 0.15 01 A5 0.10 11 0.13 10 0.15 02 A6 0.07 12 0.10 11 A7 0.07 010 0.07 12 A8 0.05 011 A9 0.03 012 频度中的黑体为前一频度列表中斜体频度相加而得。编码后字符A1~A9的码字依次为:2,00,02,10,11,12,010,011,012。 构造三进制霍夫曼编码伪码程序如下: HUFFMAN(C) 1n←∣C∣ 2Q←C 3for i←1ton-1 4do allocateanewnodes 5left[s]←x←EXTRACT-MIN(Q) 6middle[s]←y←EXTRACT-MIN(Q) 7right[s]←z←EXTRACT-MIN(Q) 8f[s]←f[x]+f[y]+f[z] 9INSERT(Q,z) 10return EXTRACT-MIN(Q) ※霍夫曼编码(三进制)最优性证明

霍夫曼编码

霍夫曼编码 四川大学计算机学院2009级戚辅光 【关键字】 霍夫曼编码原理霍夫曼译码原理霍夫曼树霍夫曼编码源代码霍夫曼编码分析霍夫曼编码的优化霍夫曼编码的应用 【摘要】 哈夫曼编码(Huffman Coding)是一种编码方式,哈夫曼编码是可变字长编码(VLC)的一种。uffman于1952年提出一种编码方法,该方法完全依据字符出现概率来构造异字头的平均长度最短的码字,有时称之为最佳编码,一般就叫作Huffman 编码。哈夫曼压缩是个无损的压缩算法,一般用来压缩文本和程序文件。它属于可变代码长度算法一族。意思是个体符号(例如,文本文件中的字符)用一个特定长度的位序列替代。因此,在文件中出现频率高的符号,使用短的位序列,而那些很少出现的符号,则用较长的位序列。 【正文】 引言 哈夫曼编码(Huffman Coding)是一种编码方式,哈夫曼编码是可变字长编码(VLC)的一种。uffman于1952年提出一种编码方法,该方法完全依据字符出现概率来构造异字头的平均长度最短的码字,有时称之为最佳编码,一般就叫作Huffman编码。 霍夫曼编码原理: 霍夫曼编码的基本思想:输入一个待编码的串,首先统计串中各字符出现的次数,称之为频次,假设统计频次的数组为count[],则霍夫曼编码每次找出count数组中的值最小的两个分别作为左右孩子,建立他们的父节点,循环这个操作2*n-1-n(n是不同的字符数)次,这样就把霍夫曼树建好了。建树的过程需要注意,首先把count数组里面的n个值初始化为霍夫曼树的n个叶子节点,他们的孩子节点的标号初始化为-1,父节点初始化为他本身的标号。接下来是编码,每次从霍夫曼树的叶子节点出发,依次向上找,假设当前的节点标号是i,那么他的父节点必然是myHuffmantree[i].parent,如果i是myHuffmantree[i].parent 的左节点,则该节点的路径为0,如果是右节点,则该节点的路径为1。当向上找到一个节点,他的父节点标号就是他本身,就停止(说明该节点已经是根节点)。还有一个需要注意的地方:在查找当前权值最小的两个节点时,那些父节点不是他本身的节点不能考虑进去,因为这些节点已经被处理过了。 霍夫曼树:

霍夫曼编码的MATLAB实现(完整版).pdf

%哈夫曼编码的 MATLAB 实现(基于 0、1 编码):clc; clear; A=[0.3,0.2,0.1,0.2,0.2];A=fliplr(sort(A));% T=A;信源消息的概率序列按降序排列 [m,n]=size(A); B=zeros(n,n-1);% 空的编码表(矩阵)for i=1:n B(i,1)=T(i);% end 生成编码表的第一列 r=B(i,1)+B(i-1,1);% 最后两个元素相加T(n-1)=r; T(n)=0; T=fliplr(sort(T) );t=n-1; for j=2:n-1% 生成编码表的其他各列for i=1:t B(i,j)=T(i) ;end K=find(T==r); B(n,j)=K(end);% %该列的位置 从第二列开始,每列的最后一个元素记录特征元素在r=(B(t- 1,j)+B(t,j));% T(t-1)=r;最后两个元素相加T(t)=0; T=fliplr(sort(T) ); t=t-1; end B;%输出编码表 END1=sym('[0,1]');% 给最后一列的元素编码END=END1; t=3; d=1; for j=n-2:-1:1% 从倒数第二列开始依次对各列元素编码for i=1:t-2 if i>1 & B(i,j)==B(i- 1,j)d=d+1; else d=1;end B(B(n,j+1),j+1)=-1; temp=B(:,j+1);

x=find(temp==B(i,j)); END(i)=END1(x(d)); end y=B(n,j+1); END(t-1)=[char(END1(y)),'0']; END(t)=[char(END1(y)),'1']; t=t+1; END1=END; end A% 排序后的原概率序列 END% 编码结果 for i=1:n [a,b]=size(char(END(i))) ; L(i)=b; end avlen=sum(L.*A)% 平均码长 H1=log2(A); H=-A*(H1')% 熵 P=H/avlen%编码效率 2

哈夫曼树编码实验报告

、 数据结构课程设计 报告 题目:哈夫曼编码/译码 学院数学与信息科学学院 学科门类理科 专业数学类 学号2013433033 姓名田娟 2014年12 月30日

目录 一、需求分析 1.程序的功能 (3) 2.输入输出的要求 (3) 3.测试数据 (3) 二、概要设计 1.本程序所用的抽象数据类型的定义 (3) 2.主程序模块 (3) 3.主模块的流程及各子模块的主要功能 (4) 4.模块之间的层次关系 (4) 三、详细设计 1.采用c语言定义相关的数据类型 (4) 2. 伪码算法 (5) 四、调试分析 1.调试中遇到的问题及对问题的解决方法 (15) 五、使用说明及测试结果 1.建立哈夫曼树,输入叶子结点个数,权值,字符集 (15) 2.编码 (15) 3.译码 (16) 4.显示码文 (16) 5.显示哈夫曼树 (16) 六、源程序

一、需求分析 1.程序的功能; 哈夫曼编码是一种应用广泛而有效的数据压缩技术。利用哈夫曼编码进行通信可以大大提高信道利用率,加快信息传输速度,降低传输成本。数据压缩的过程称为编码,解压缩的过程称为译码。进行信息传递时,发送端通过一个编码系统对待传数据(明文)预先编码,而接收端将传来的数据(密文)进行译码。 2.输入输出的要求;: 2.1.构造哈夫曼树及哈夫曼编码:从终端读入字符集大小n、n个字符以及n个对应的权值,建立哈夫曼树;利用已经建好的哈夫曼树求每个叶结点的哈夫曼编码,并保存。 2.2编码:利用已构造的哈夫曼编码对“明文”文件中的正文进行编码,然后将结果存入“密文”文件中。 2.3.译码:将“密文”文件中的0、1代码序列进行译码。 2.4.打印“密文”文件:将文件以紧凑格式显示在终端上,每行30个代码;同时,将此字符形式的编码文件保存。 2.5.打印哈夫曼树及哈夫曼编码:将已在内存中的哈夫曼树以凹入表形式显示在终端上,同时将每个字符的哈夫曼编码显示出来;并保存到文件。 3.测试数据。 3.1.令叶子结点个数N为4,权值集合为{1,3,5,7},字符集合为{A,B,C,D},且字符集与权值集合一一对应。 3.2.请自行选定一段英文文本,统计给出的字符集,实际统计字符的频度,建立哈夫曼树,构造哈夫曼编码,并实现其编码和译码。 二、概要设计 1.本程序所用的抽象数据类型的定义; class HuffmanTree //哈夫曼树 { private: HuffmanNode *Node; //Node[]存放哈夫曼树 int LeafNum; //哈夫曼树的叶子个数,也是源码个数 2.主程序模块 main() 2.2 建立哈夫曼树函数 // 函数功能:建立哈夫曼树 void HuffmanTree::CreateHuffmanTree() 2.3 函数功能:为哈夫曼树编码

相关文档
最新文档