完整word版数据结构哈夫曼编码源代码

合集下载

数据结构哈夫曼树的代码

数据结构哈夫曼树的代码

数据结构哈夫曼树的代码<h1>哈夫曼树数据结构</h1><h2>1.引言</h2><p>哈夫曼树是一种常用于数据压缩和编码的树状结构。

它在通信和存储领域中有着广泛的应用,并且已经成为理解其他数据结构的基础知识之一。

本文档将介绍哈夫曼树的定义、构建和操作等基本内容。

</p><h2>2.哈夫曼树的定义</h2><p>哈夫曼树是一种特殊的二叉树,它具有以下特征:</p><ul><li>每个叶子节点都代表一个字符或符号</li><li>每个内部节点的权重(权值)为其所有子节点权重的和</li><li>树的带权路径长度(WPL)最小</li></ul><h2>3.哈夫曼树的构建</h2><p>构建哈夫曼树的基本步骤如下:</p><ol><li>将输入的字符或符号按照权重从小到大排序</li><li>选取权重最小的两个节点作为左右子节点,构建一个新的父节点,将父节点的权重设置为子节点权重之和</li> <li>将新的父节点插入到已排序的节点列表中,并保持节点列表的有序性</li><li>重复步骤2和步骤3,直到所有节点都被合并为一个根节点</li></ol><h2>4.哈夫曼编码</h2><p>哈夫曼编码是一种将字符或符号转换为二进制位串的编码方式。

在哈夫曼树中,从根节点到叶子节点的路径上的边用0和1表示,其中左边的路径标记为0,右边的路径标记为1.通过前缀编码的方式,哈夫曼编码具有唯一性和无歧义性。

(完整word版)哈夫曼编码编译器

(完整word版)哈夫曼编码编译器

一、课题:哈夫曼编码编译器设计一个哈夫曼编码/译码系统,对一个文本文件中的字符进行哈夫曼编码,生成编码文件(压缩文件,后缀名.cod);反过来,可将一个压缩文件译码还原为一个文本文件(.txt)。

二、功能(1)输入一个待压缩的英文文本文件,统计文本文件中各字符的个数作为权值,生成哈夫曼树;(2)将文本文件利用哈夫曼树进行编码,生成压缩文件(后缀名cod)(3)输入一个待解压的压缩文件名称,并利用相应的哈夫曼树将编码序列译码。

三、程序结构程序流程图文字说明Main函数:Coding()编码函数TransCode()译码函数Coding()编码函数:clearscreen()清屏函数Open()打开源码文件SearchStr()查找字符串中不同的字符及其出现的次数CreatHFMTree()用每个字符出现的次数作为叶子节点的权值建立哈夫曼树HFMCode()利用哈夫曼树对每个叶子节点进行编码,存入编码表中TotalCoding()利用编码表对字符串进行最终编码Save()保存最终的哈夫曼编码TransCode()译码函数:clearscreen()清屏函数Open()打开编码文件DeCoding(); //将编码进行解码存入字符串数组中Save(); //保存译码后的字符串四、算法说明1.执行界面可供三个选择(1)编码(2)译码(3)退出执行(1)选择需要输入要编译的文件名需要输出编码保存文件名选择(1)执行完毕执行(2)选项输入要译码的编码文件名并输入保存的文件名选择(2)执行完毕执行(0)则退出该程序五、报告总结该程序主要采用了哈夫曼编码译码方法,对txt文件进行编译压缩,同时也能对编码后的文件进行解码,程序结构清晰,主干分两大部分:编码部分与解码部分,各部分通过调用函数合理清晰的实现其功能。

程序中运用了一些文件的C语言基本操作,例如打开文件open()、保存文件save()函数,但程序上对文件类型的处理还有一些缺点,不能实现文件类型的自动保存,需要输入文件名字和类型。

哈夫曼编码器-源代码

哈夫曼编码器-源代码

#include <stdio.h>#include <string.h>#include <stdlib.h>typedef struct{char data;int weight;int parent;int lchild;int rchild;}HTNode;HTNode ht[30];typedef struct{char cd[30];int start;}HCode;HCode hcd[30];void CreateHT( HTNode ht[] , int n ) {int i , k , lnode, rnode ;int min1 , min2 ;for ( i = 0 ; i < 2*n-1 ; i++ ){ht[i].parent = ht[i].lchild = ht[i].rchild = 0;}for ( i = n ; i < 2*n-1 ; i++ ){min1 = min2 = 32767;lnode = rnode = 0;for ( k=0 ; k <= i-1; k++)if ( ht[k].parent == 0) {if (ht[k].weight < min1){min2 = min1;min1 = ht[k].weight;rnode = lnode;lnode = k;}else if ( ht[k].weight < min2){min2 = ht[k].weight;rnode = k;}}ht[lnode].parent = i;ht[rnode].parent = i;ht[i].weight = ht[lnode].weight + ht[rnode].weight;ht[i].lchild = lnode;ht[i].rchild = rnode;}}void CreateHCode( HTNode ht[] , HCode hcd[] , int n ){int i , f , c;HCode hc;for( i = 0 ; i < n; i++){hc.start = n;c = i;f = ht[i].parent;while (f != 0){if( ht[f].lchild == c){hc.cd[hc.start--] = '0';}else{hc.cd[hc.start--] = '1';}c=f ;f=ht[f].parent;}hc.start++;hcd[i] = hc;}}void CodeInput(int n,HTNode ht[]){int i;char ch[30];scanf( "%s" , ch );for ( i=0 ; i<n ; i++ ){scanf( "%ld" , &ht[i].weight );}printf("######################################- \n"); }void CodeOutput( int n , HCode hcd[] ){int i , j ;printf (" 所有字符的哈弗曼编码为:");for ( i = 0 ; i < n ; i++ ){for( j=hcd[i].start ; j<=n ; j++ ){printf( "%lc" , hcd[i].cd[j] );}}printf("\n");for ( i=0 ; i<n ; i++ ){printf( " 序号%d : " , i );for( j = hcd[i].start ; j <= n ; j++ ){printf( "%lc" , hcd[i].cd[j] );}printf( "\n" );}}void save( int n ){int i ;FILE *fp;if( ( fp = fopen ( "c:\\data.txt" , "w" ) ) == NULL ) {printf( " can't open this file !!! " ) ;exit(0) ;}else{for ( i = 1 ; i <= n ; i++ ){fprintf( fp , " %ld ", ht[i].weight );}printf(" You have saved it successful !!!");}fclose (fp) ;}void main(){ int num ;char flag ='y';while( flag == 'y' || flag == 'Y' ){system( "cls" );printf(" ################################ \n");printf(" 欢迎使用哈夫曼编码系统\n ");printf(" ################################ \n");printf(" ######## 1. 生成哈夫曼树#########\n");printf(" ######### 2. 哈夫曼编码######### \n");printf(" ######### 3.哈夫曼权值存储######### \n");printf(" ######## 4. 退出########\n");printf(" ##############################\n");printf(" 请选择操作类型( 1 - 4 ) : " );scanf( " %d" , &num );printf("############################################ \n");switch(num){case 1 :int n , i ;printf(" 请输入要输入的字符数量n为: ");if((scanf(" %ld", &n ))&&(n!=0)){printf("\n 请输入%d 个字符和%d 个对应权值<先将所有字符输入再输对应权值> \n 在此输入: " , n , n );CodeInput( n , ht );CreateHT( ht , n );printf(" 对应的权值为:\n");for( i = 0 ; i < n ; i++ ){printf( " %d : %ld " , i , ht[i].weight );if((i+1) % 4 == 0){printf("\n");}}}printf("\n######################################- \n");break;case 2 :CreateHCode( ht , hcd , n );CodeOutput( n , hcd );printf("##############################################-");break;case 3 :save(n);printf("#######################################");break;case 4 :printf("############# **感谢使用本程序** ############### \n ");exit(1);printf("########################################");break;default :printf(" Error ! You must put the number between <1 -- 4> ");printf("\n#####################################\n");}printf(" \n 继续或退出(y or n) : ");getchar() ;flag=getchar();}}。

数据结构哈夫曼编码

数据结构哈夫曼编码

Main.c文件如下#include <stdio.h>#include <stdlib.h>#include <malloc.h>#include "Haffman.h"#define MaxBit 100void main(void){ Code *d;int i,j,n=26,m,weight[26]={0};char c,a=97;FILE *fp; //文本文件指针if((fp=fopen("data.txt","r"))==NULL){printf("无法打开此文件\n");exit(0); //中止程序}printf("待压缩的英文文本文件为:\n");while(!feof(fp)) //当扫描文件内容没有结束时{//读取字符并统计每个字符次数c=fgetc(fp);putchar(c);if(c>='a'||c<='z');c=c-32;for (i=65;i<=90;i++)if(c==i)weight[i-65]++ ;}fclose(fp);HaffNode *myHaffTree=(HaffNode *)malloc(sizeof(HaffNode)*(2*n-1));Code *myHaffCode=(Code *)malloc(sizeof(Code)*n);Haffman(weight,n,myHaffTree);HaffmanCode(myHaffTree,n,myHaffCode);for(m=0;m<n;m++){printf("\nzimu=%c Weight=%d Code=",a++,myHaffCode[m].weight);for(j=myHaffCode[m].start;j<n;j++)printf("%d",myHaffCode[m].bit[j]);printf("\n");}}头文件Huffman.h如下#ifndef Haffman_H_INCLUDED#define Haffman_H_INCLUDED#define MaxN 300#define MaxValue 10000typedef struct{int weight; //权值int flag; //标记int parent; //双亲结点下标int leftChild; //左孩子下标int rightChild; //右孩子下标}HaffNode; //哈夫曼树的结点结构typedef struct{int bit[MaxN]; //数组int start; //编码的起始下标int weight; //字符的权值}Code; //哈弗曼编码的结构void Haffman(int weight[],int n,HaffNode haffTree[])//建立叶节点个数为n,权值数组为weight的哈弗曼树haffTree{int i,j,m1,m2,x1,x2;//哈夫曼树haffTree初始化,n个叶节点的二叉树共有2n-1个结点for(i=0;i<2*n-1;i++){if(i<n) haffTree[i].weight=weight[i];else haffTree[i].weight=0;haffTree[i].parent=-1;haffTree[i].flag=0;haffTree[i].leftChild=-1;haffTree[i].rightChild=-1;}//构造哈弗曼树的n-1个非叶节点for(i=0;i<n-1;i++){m1=m2=MaxValue;x1=x2=0;for(j=0;j<n+i;j++) //找出权值最小和次小的子树{if((haffTree[j].weight<m1) && (haffTree[j].flag==0)){m2=m1;x2=x1;m1=haffTree[j].weight;x1=j;}else if((haffTree[j].weight<m2) && (haffTree[j].flag==0)){m2=haffTree[j].weight;x2=j;}}//将找出两棵权值最小和次小的子树合并为一棵子树haffTree[x1].parent=n+i;haffTree[x2].parent=n+i;haffTree[x1].flag=1;haffTree[x2].flag=1;haffTree[n+i].weight=haffTree[x1].weight+haffTree[x2].weight;haffTree[n+i].leftChild= x1;haffTree[n+i].rightChild=x2;}}void HaffmanCode(HaffNode haffTree[],int n,Code haffCode[])//由n个结点的哈夫曼树构造哈弗曼编码{Code *cd=(Code *)malloc(sizeof(Code));int i,j,child,parent;//求n个叶节点的哈弗曼编码for(i=0;i<n;i++){cd->start=n-1; //不等长编码的最后一位n-1cd->weight=haffTree[i].weight; //取得编码对应权值child=i;parent=haffTree[child].parent;//由叶节点向上直到根节点while(parent!=-1){if(haffTree[parent].leftChild==child)cd->bit[cd->start]=0; //左孩子分支编码0elsecd->bit[cd->start]=1; //左孩子分支编码1cd->start--;child=parent;parent=haffTree[child].parent;}for(j=cd->start+1;j<n;j++)haffCode[i].bit[j]=cd->bit[j]; //保存每个叶节点编码haffCode[i].start=cd->start+1; //保存叶节点编码的起始位haffCode[i].weight=cd->weight; //保存编码对应权值}}#endif // HFM_H_INCLUDED。

哈夫曼编码算法实现完整版

哈夫曼编码算法实现完整版

实验三树的应用一.实验题目:树的应用——哈夫曼编码二.实验内容:利用哈夫曼编码进行通信可以大大提高信道的利用率,缩短信息传输的时间,降低传输成本。

根据哈夫曼编码的原理,编写一个程序,在用户输入结点权值的基础上求哈夫曼编码。

要求:从键盘输入若干字符及每个字符出现的频率,将字符出现的频率作为结点的权值,建立哈夫曼树,然后对各个字符进行哈夫曼编码,最后打印输出字符及对应的哈夫曼编码。

三、程序源代码:#include <iostream.h>#include <fstream.h>#include <string.h>#include <stdlib.h>typedef struct{char data;int weight;int parent,lchild,rchild;}HTNode,*HuffmanTree;typedef char * * HuffmanCode;void Select(HuffmanTree &HT,int n,int m){HuffmanTree p=HT;int tmp;for(int j=n+1;j<=m;j++){int tag1,tag2,s1,s2;tag1=tag2=32767;for(int x=1;x<=j-1;x++){ if(p[x].parent==0&&p[x].weight<tag1){ tag1=p[x].weight;s1=x;}}for(int y=1;y<=j-1;y++){ if(p[y].parent==0&&y!=s1&&p[y].weight<tag2){ tag2=p[y].weight;s2=y;}}if(s1>s2) //将选出的两个节点中的序号较小的始终赋给s1{ tmp=s1; s1=s2; s2=tmp;}p[s1].parent=j;p[s2].parent=j;p[j].lchild=s1;p[j].rchild=s2;p[j].weight=p[s1].weight+p[s2].weight;}}void HuffmanCoding(HuffmanTree &HT,int n,char *w1,int*w2){int m=2*n-1;if(n<=1) return;HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode));HuffmanTree p=HT;for(int i=1;i<=n;i++){ p[i].data=w1[i-1];p[i].weight=w2[i];p[i].parent=p[i].lchild=p[i].rchild=0;}for(;i<=m;i++){ p[i].weight=p[i].parent=p[i].lchild=p[i].rchild=0; }Select(HT,n,m);ofstream outfile; //生成hfmTree文件outfile.open("hfmTree.txt",ios::out);for (i=1;i<=m;i++){outfile<<HT[i].weight<<"\t"<<HT[i].parent<<"\t"<<HT[i].lchild<<"\t"<<HT[i].rchild<<"\t"<<endl;}outfile.close();cout<<"初始化结果已保存在hfmTree文件中\n";}void ToBeTree() //将正文写入文件ToBeTree中{ofstream outfile;outfile.open("ToBeTree.txt",ios::out);outfile<<"THIS PROGRAM IS MYFA VORITE";outfile.close();}void Encoding(HuffmanTree &HT,int n) //编码{HuffmanCode HC;HC=(HuffmanCode)malloc((n+1)*sizeof(char *));char *cd;cd=(char *)malloc(n*sizeof(char));cd[n-1]='\0';for(int k=1;k<=n;k++){ int start=n-1;for(int c=k,f=HT[k].parent;f!=0;c=f,f=HT[f].parent){ if(HT[f].lchild==c) cd[--start]='0';else cd[--start]='1';}HC[k]=(char *)malloc((n-start)*sizeof(char));strcpy(HC[k],&cd[start]);}cout<<"输出哈夫曼编码:"<<endl;for(int h=1;h<=n;h++) //输出编码{ cout<<HT[h].data<<":";cout<<HC[h];cout<<" ";if (h%8==0) cout<<endl;}cout<<endl<<"输出正文编码:"<<endl;ToBeTree();//读取TOBETREE文件里的正文,并进行编码fstream infile;infile.open("ToBeTree.txt",ios::in);char s[80];while(!infile.eof()){infile.getline(s,sizeof(s));}infile.close();fstream outfile;outfile.open("CodeFile.txt",ios::out);int count=0;for (h=0;s[h]!='\0';h++){ for(k=1;k<=n;k++)if (s[h]==HT[k].data){ cout<<HC[k];cout<<" ";count++;outfile<<HC[k];break;}if (count%9==0) cout<<endl; //每输出7个换行}outfile.close();cout<<"\n编码结果已保存在文件CodeFile中.";cout<<endl;}void Decoding(HuffmanTree &HT,int n) //译码{int f=2*n-1;fstream infile;infile.open("CodeFile.txt",ios::in);char s[1000];while(!infile.eof()){infile.getline(s,sizeof(s));}infile.close();int i=0;int j=0;fstream outfile;outfile.open("TextFile.txt",ios::out);while(s[i]!='\0'){ f=2*n-1;while(HT[f].lchild!=0)//以f对应的节点的左孩子的值==0作为结束{if (s[j]=='0') f=HT[f].lchild;else f=HT[f].rchild;j++;}i=j;cout<<HT[f].data;outfile<<HT[f].data;}outfile.close();cout<<"\n译码结果已保存在文件TextFile中.";cout<<endl;}void Print() //印代码文件{ int count=0;fstream infile;infile.open("CodeFile.txt",ios::in);char s[1000];while(!infile.eof()){infile.getline(s,sizeof(s));for(int i=0;s[i]!='\0';i++){ cout<<s[i];count++;if (count%50==0) cout<<endl; //在终端上每行显示50个代码}}infile.close();cout<<endl;}char menu() //菜单函数{ cout<<"功能菜单如下:"<<endl;cout<<"* * * * * * * * * * * * * * * * * * * * *"<<endl;cout<<" I:初始化(Initialization) "<<endl;cout<<" E:编码(Encoding) "<<endl;cout<<" D:译码(Decoding) "<<endl;cout<<" P:印代码文件(Print) "<<endl;cout<<" Q:退出(Exit) "<<endl;cout<<"* * * * * * * * * * * * * * * * * * * * *"<<endl;cout<<"请输入功能字符:";char ch;cin>>ch;return ch;}void main(){ int n;int Array[100];char cArray[100];HuffmanTree HT;cout<<"输入n个字符:";cin.getline(cArray,100);n=strlen(cArray);cout<<"一共"<<n<<"个字符.\n";cout<<"依次输入各个字符的权值:"<<endl;for (int i=1;i<=n;i++) cin>>Array[i];int tag;char x=menu();while(1){ switch (x){case 'I':HuffmanCoding(HT,n,cArray,Array);break;case 'E':Encoding(HT,n);break;case 'D':Decoding(HT,n);break;case 'P':Print();break;case 'Q':tag=0;cout<<"结束"<<endl;break;default:cout<<"你输入错误!"<<endl;}if(tag==0) break;cout<<"y(继续) or n(退出)"<<endl;char ch;cin>>ch;if (ch=='y'){ cout<<"请输入功能字符:";char c;cin>>c;x=c;}else exit(1);}}测试数据:用下表给出的字符集和频度的实际统计数据建立哈夫曼树,并实现以下报文的译码和编码:"THIS PROGRAM IS MY FAVORITE".字符空格 A B C D E F G H I J K L M频度186 64 13 22 32 103 21 15 47 57 1 5 32 20字符N O P Q R S T U V W X Y Z频度57 63 15 1 48 51 80 23 8 18 1 16 1四.测试结果:如图一所示五.实验体会通过本次实验,尤其在自己对程序的调试过程中,感觉对树的存储结构,终结状态,还有编码,译码的过程都有了比较清晰的认识。

哈夫曼编码程序代码

哈夫曼编码程序代码

#include<iostream.h>#include<stdio.h>#include<stdlib.h>#include<string.h>#include<fstream.h>typedef struct{char ch;int weight;int parent,lchild,rchild;}htnode,*hfmtree;typedef char **hfmcode;void Select(hfmtree &HT,int a,int *p1,int *p2){int i,j,x,y;for(j=1;j<=a;++j){if(HT[j].parent==0){x=j;break;}}for(i=j+1;i<=a;++i){if(HT[i].weight<HT[x].weight&&HT[i].parent==0){x=i;}}for(j=1;j<=a;++j) {if(HT[j].parent==0&&x!=j){y=j;break;}}for(i=j+1;i<=a;++i){if(HT[i].weight<HT[y].weight&&HT[i].parent==0&&x!=i){y=i;}}if(x>y){*p1=y;*p2=x;}else{*p1=x;*p2=y;}}void hfmcoding(hfmtree &HT,hfmcode &HC,int n) {int i,start,c,f,m,w;int p1,p2;char *cd,z;if(n<=1){return;}m=2*n-1;HT=(hfmtree)malloc((m+1)*sizeof(htnode));for(i=1;i<=n;++i){printf("请输入第%d字符信息和权值:",i);scanf("%c%d",&z,&w);while(getchar()!='\n'){continue;}HT[i].ch=z;HT[i].weight=w;HT[i].parent=0;HT[i].lchild=0;HT[i].rchild=0;}for(;i<=m;++i){HT[i].ch='0';HT[i].weight=0;HT[i].parent=0;HT[i].lchild=0;HT[i].rchild=0;}for(i=n+1;i<=m;++i){Select(HT,i-1,&p1,&p2);HT[p1].parent=i;HT[p2].parent=i;HT[i].lchild=p1;HT[i].rchild=p2;HT[i].weight=HT[p1].weight+HT[p2].weight;}HC=(hfmcode)malloc((n+1)*sizeof(char *));cd=(char *)malloc(n*sizeof(char));cd[n-1]='\0';for(i=1;i<=n;++i){start=n-1;for(c=i,f=HT[i].parent;f!=0;c=f,f=HT[f].parent){if(HT[f].lchild==c){cd[--start]='0';}else{cd[--start]='1';}}HC[i]=(char*)malloc((n-start)*sizeof(char));strcpy(HC[i],&cd[start]);}free(cd);}int main(){char code[100],h[100],hl[100];int n,i,j,k,l;ifstream input_file;ofstream output_file;char choice,str[100];hfmtree HT;hfmcode HC;cout<<"\n";while(choice!='Q'&&choice!='q'){cout<<" "<<"*************************赫夫曼编码/译码器*************************\n";cout<<" "<<"I.Init"<<" "<<"E.Encoding"<<" "<<"D.Decoding"<<" "<<"Q.Exit\n";cout<<"请输入您要操作的步骤:";cin>>choice;if(choice=='I'||choice=='i'){cout<<"请输入字符个数:";cin>>n;hfmcoding(HT,HC,n);for(i=1;i<=n;++i){cout<<HT[i].ch<<":"<<HC[i]<<endl;}output_file.open("hfmTree.txt");if(!output_file){cout<<"can't oen file!"<<endl;return 1;}for(i=1;i<=n;i++){output_file<<"("<<HT[i].ch<<HC[i]<<")";}output_file.close();cout<<"赫夫曼树已经创建完毕,并且已经放入hfmTree.txt文件中!"<<endl; }else if(choice=='E'||choice=='e'){printf("请输入字符:");gets(str);output_file.open("ToBeTran.txt");if(!output_file){cout<<"can't oen file!"<<endl;return 1;}output_file<<str<<endl;output_file.close();output_file.open("CodeFile.txt");if(!output_file){cout<<"can't oen file!"<<endl;return 1;}for(i=0;i<strlen(str);i++){for(j=0;j<=n;++j){if(HT[j].ch==str[i]){output_file<<HC[j];break;}}}output_file.close();cout<<"\n";cout<<"编码完毕,并且已经存入CodeFile.txt文件!\n";input_file.open("CodeFile.txt");if(!input_file){cout<<"can't oen file!"<<endl;return 1;}input_file>>code;cout<<"编码码值为:"<<code<<endl;input_file.close();}else if(choice=='D'||choice=='d'){input_file.open("CodeFile.txt");if(!input_file){cout<<"can't oen file!"<<endl;return 1;}input_file>>h;input_file.close();output_file.open("Textfile.txt");if(!output_file){cout<<"can't oen file!"<<endl;return 1;}k=0;while(h[k]!='\0') {for(i=1;i<=n;i++){l=k;for(j=0;j<strlen(HC[i]);j++,l++){hl[j]=h[l];}hl[j]='\0';if(strcmp(HC[i],hl)==0){output_file<<HT[i].ch;k=k+strlen(HC[i]);break;}}}output_file.close();input_file.open("Textfile.txt");if(!input_file){cout<<"can't oen file!"<<endl;return 1;}input_file>>h;cout<<h<<endl;input_file.close();cout<<"译码结束,字符已经存入Textfile.txt文件中!"<<endl;}else if(choice=='Q'||choice=='q') \{exit(0);}else{cout<<"您没有输入正确的步骤,请重新输入!"<<endl;}cout<<endl;}return 0;}。

(2021年整理)哈夫曼编码_汉明编码

(2021年整理)哈夫曼编码_汉明编码

(完整)哈夫曼编码_汉明编码编辑整理:尊敬的读者朋友们:这里是精品文档编辑中心,本文档内容是由我和我的同事精心编辑整理后发布的,发布之前我们对文中内容进行仔细校对,但是难免会有疏漏的地方,但是任然希望((完整)哈夫曼编码_汉明编码)的内容能够给您的工作和学习带来便利。

同时也真诚的希望收到您的建议和反馈,这将是我们进步的源泉,前进的动力。

本文可编辑可修改,如果觉得对您有帮助请收藏以便随时查阅,最后祝您生活愉快业绩进步,以下为(完整)哈夫曼编码_汉明编码的全部内容。

1 课题描述信息论理论基础的建立,一般来说开始与香农(C.E。

Shannon)在研究通信系统时所发表的论文。

信息论是在信息可以度量的基础上,对如何有效、可靠的传递信息进行研究的科学,它涉及信息亮度、信息特性、信息传输速率、信道容量、干扰对信息传输的影响等方面的知识。

通常把上述范围的信息论称为狭义信息论,又因为它的创始人是香农,故又称为香农信息论。

广义信息论则包含通信的全部统计问题的研究,除了香农信息论之外,还包括信号设计、噪声理论、信号的检测与估值等。

当信息在传输、存储和处理的过程中,不可避免的要受到噪声或其他无用信号的干扰时,信息理论会为可靠、有效的从数据中提取信息提供必要的根据和方法。

因此必须研究噪声和干扰的性质以及它们与信息本质上的差别,噪声与干扰往往具有某种统计规律的随机特性,信息则具有一定的概率特性,如度量信息量的熵值就是概率性质的。

信息论、概率轮、随机过程和数理统计学是信息论应用的基础和工具。

信息论主要研究如何提高信息系统的可靠性、有效性、保密性和认证性,以使信息系统最优化.所谓可靠性高就是要使信源发出的消息经过信道传输以后,尽可能准确的、不失真的再现在接收端;而所谓有效性高,就是经济效果好,即用尽可能少的资源和尽可能少的设备来传送一定数量的信息;所谓保密性就是隐蔽和保护通信系统中传送的信息,使它只能被授权接受者获取,而不能被未授权者接受和理解;而认证性是指接受者能正确的判断所接受的消息的正确性,验证消息的完整性,而不是接收伪造的和被修改的信息。

完整word版哈夫曼编码译码器数据结构C语言模板

完整word版哈夫曼编码译码器数据结构C语言模板

一、需求分析目前,进行快速远距离通信的主要手段是电报,即将需传送的文字转化成由二级制的字符组成种字符,只需两个字符的串,便可”,它只有4的字符串。

例如,假设需传送的电文为“ABACCDA,00010010101100”则上述和11,7个字符的电文便为“以分辨。

假设A、B、C、D、的编码分别为00,01,10 14位,对方接受时,可按二位一分进行译码。

总长当然,在传送电文时,希望总长尽可能地短。

如果对每个字符设计长度不等的编码,且让电文DC、中出现次数较多的字符采用尽可能短的编码,则传送电文的总长便可减少。

如果设计A、B、。

但是,000011010”,则上述7个字符的电文可转换成总长为9的字符串“的编码分别为0,00,1,01”就可以有很多种译法,0000个字符的字串“这样的电文无法翻译,例如传送过去的字符串中前4”等。

因此,若要设计长短不等的编码,则必须是任一字ABAAAAA”或者“BB”,或者“或是“符的编码都不是另一个字符的编码的前缀,这种编码称作前缀编码。

然而,如何进行前缀编码就是利用哈夫曼树来做,也就有了现在的哈夫曼编码和译码。

二、概要设计译码利用哈夫曼树编/ 、建立哈夫曼树(一)、对哈夫曼树进行编码(二)、输出对应字符的编码(三)、译码过程(四)主要代码实现://结构体的定义struct code{char a;int w;int parent;int lchild;int rchild;};void creation(code *p,int n,int m); //建立哈夫曼树//编码void coding(code *p,int n);//输出函数void display(code *p,int n,int m);//译码void translate(char **hc,code *p,int n);详细设计三、(一)、建立哈夫曼树10序号:5 3 4 2 7 6 1* * *c *字符:db a 4 6 6 权值:10 6 4 2 3 3 1 d **33333 c*c * * 1 2 2 1 2 1 abb a 3-3图3-1 图b a 3-2 图1(二)、对哈夫曼树进行编码主要代码实现:从叶子到根逆向求编码for(c=i,f=p[i].parent;f!=0;c=f,f=p[f].parent){*'0'//左孩子编码为if(p[f].lchild==c) 1 { d* cd[--start]='0'; 0 1} c* 1 0 '1'else //右孩子编码为{ bacd[--start]='1';3-4图}}(三)、输出对应字符的码编码字符110 a111 b10 c3-1表d(四)、译码过程主要代码实现:0 比较两个字符串是否相等,相等则输出if(strcmp(a,hc[i])==0) //{或'1'确定找左孩子或右孩子//从根出发,按字符'0' for(c=2*n-1,j=0;a[j]!='\0';j++){if(a[j]=='0') //左孩子从跟到叶子顺向求字符{*c=p[c].lchild;1 0}d * else 1 0{c *右孩子c=p[c].rchild; // 1 0}ba }3-5 图2调试分析四、、数字的输入判断(一)4-1 图、字母的输入判断(二)4-2 图(三)、程序是否继续进行的判断4-3 图用户手册五、;提示输(一)、首先根据提示输入初始化数据,提示输入一个数字,请输入一个数a,0<a<9999中的一个字符;请勿在输入一个数字后再输入一个入一个字母,则请输入一个字母(a~z)或者(A~Z) 字符,或者在输入一个字符后再输入一个数字。

(完整word版)数据结构哈夫曼编码与译码

(完整word版)数据结构哈夫曼编码与译码

《数据结构》课程设计说明书题目哈夫曼编码与译码学号1267159206姓名张燕斌指导教师康懿日期2014.01。

02任务书目录第一章需求分析 (5)第二章总体设计 (6)第三章抽象数据类型定义 (7)3。

1 LinkList抽象数据类型的设计 (7)3.2 HuffmanTree抽象数据的设计 (7)第四章详细设计..。

...。

..。

....。

.....。

.。

.。

..。

.。

....。

.。

..。

..。

.。

.。

.。

.。

..。

....。

....。

.。

..。

...。

...。

7第五章测试 (10)第六章总结 (11)附录:程序代码 (12)第一章需求分析哈夫曼编码是一种编码方式,以哈夫曼树—即最优二叉树,带权路径长度最小的二叉树,经常应用于数据压缩。

哈弗曼编码使用一张特殊的编码表将源字符(例如某文件中的一个符号)进行编码。

这张编码表的特殊之处在于,它是根据每一个源字符出现的估算概率而建立起来的(出现概率高的字符使用较短的编码,反之出现概率低的则使用较长的编码,这便使编码之后的字符串的平均期望长度降低,从而达到无损压缩数据的目的)。

赫夫曼编码的应用很广泛,利用赫夫曼树求得的用于通信的二进制编码称为赫夫曼编码。

树中从根到每个叶子都有一条路径,对路径上的各分支约定:指向左子树的分支表示“0”码,指向右子树的分支表示“1”码,取每条路径上的“0”或“1”的序列作为和各个叶子对应的字符的编码,这就是赫夫曼编码。

哈弗曼译码输入字符串可以把它编译成二进制代码,输入二进制代码时可以编译成字符串。

第二章总体设计(1)输入一个字符串用结构体链表存储字符串中出现的不同字符及其出现的次数。

(2)定义赫夫曼数的结点结构体,把不同的字符及其在字符串中出现的次数作为叶子结点的元素及其权值,统计叶子结点的个数n,开辟可以存储2*n个结点的顺序表,来赫夫曼树的各个结点,然后按照一定的规则构造赫夫曼树。

(3)开辟一个可以存储叶子结点元素及指向存储其赫夫曼编码链表的指针的顺序表,然后从叶子结点开始向上访问,是左孩子的把“0”接进链表是右孩子的把“1”接进链表,直到根结点,然后把叶子结点的元素及存储其赫夫曼链表的头指针读入顺序表,直到把所有的叶子结点的元素及指向存储其赫夫曼编码链表的头指针读入顺序表,这样得到的赫夫曼编码是倒序的。

(完整word版)数据结构课程设计(哈夫曼编码)

(完整word版)数据结构课程设计(哈夫曼编码)

目录目录 (1)1 课程设计的目的和意义 (3)2 需求分析 (5)3 系统设计 (6)(1)设计思路及方案 (6)(2)模块的设计及介绍 (6)(3)主要模块程序流程图 (9)4 系统实现 (14)(1)主调函数 (14)(2)建立HuffmanTree (14)(3)生成Huffman编码并写入文件 (18)(4)电文译码 (19)5 系统调试 (22)小结 (25)参考文献 (26)附录源程序 (27)1 课程设计的目的和意义在当今信息爆炸时代,如何采用有效的数据压缩技术来节省数据文件的存储空间和计算机网络的传送时间已越来越引起人们的重视。

哈夫曼编码正是一种应用广泛且非常有效的数据压缩技术。

哈夫曼编码的应用很广泛,利用哈夫曼树求得的用于通信的二进制编码称为哈夫曼编码。

树中从根到每个叶子都有一条路径,对路径上的各分支约定:指向左子树的分支表示“0"码,指向右子树的分支表示“1”码,取每条路径上的“0”或“1"的序列作为和各个对应的字符的编码,这就是哈夫曼编码。

通常我们把数据压缩的过程称为编码,解压缩的过程称为解码。

电报通信是传递文字的二进制码形式的字符串。

但在信息传递时,总希望总长度尽可能最短,即采用最短码。

作为软件工程专业的学生,我们应该很好的掌握这门技术。

在课堂上,我们能过学到许多的理论知识,但我们很少有过自己动手实践的机会!课程设计就是为解决这个问题提供了一个平台。

在课程设计过程中,我们每个人选择一个课题,认真研究,根据课堂讲授内容,借助书本,自己动手实践。

这样不但有助于我们消化课堂所讲解的内容,还可以增强我们的独立思考能力和动手能力;通过编写实验代码和调试运行,我们可以逐步积累调试C程序的经验并逐渐培养我们的编程能力、用计算机解决实际问题的能力。

在课程设计过程中,我们不但有自己的独立思考,还借助各种参考文献来帮助我们完成系统。

更为重要的是,我们同学之间加强了交流,在对问题的认识方面可以交换不同的意见.同时,师生之间的互动也随之改善,我们可以通过具体的实例来从老师那学到更多的实用的知识。

哈夫曼编码原码

哈夫曼编码原码

#define INT_MAX 10000#define ENCODING_LENGTH 1000#include "stdio.h"#include "string.h"#include "malloc.h"typedef enum{none,left_child,right_child} Which;//标记是左孩子还是右孩子typedef char Elemtype;typedef struct TNode{Elemtype letter;int weight;int parent;Which sigh;char *code;}HTNode,*HuffmanTree;int n;char coding[50];//储存代码char str[ENCODING_LENGTH];//保存要翻译的句子void InitTreeNode(HuffmanTree &HT){//初始前N个结点,后M-N个结点置空int i;int w;char c;int m=2*n-1;HuffmanTree p;HT=(HuffmanTree)malloc((m)*sizeof(HTNode));printf("input %d database letter and weight",n);p=HT;getchar();for (i=1;i<=n;i++){scanf("%c%d",&c,&w);p->code='\0';p->letter=c;p->parent=0;p->sigh=none;p->weight=w;p++;getchar();}for (;i<=m;i++,p++){p->code='\0';p->letter=' ';p->parent=0;p->sigh=none;p->weight=0;}}//INITTREENODEvoid Select(HuffmanTree HT,int end,int *s1,int *s2){//在0~END之间,找出最小和次小的两个结点序号,返回S1,S2int i;int min1=INT_MAX;int min2;for (i=0;i<=end;i++){//找最小的结点序号if (HT[i].parent==0&&HT[i].weight<min1){*s1=i;min1=HT[i].weight;}}min2=INT_MAX;for(i=0;i<=end;i++){//找次小结点的序号if (HT[i].parent==0&&(*s1!=i)&&min2>HT[i].weight){*s2=i;min2=HT[i].weight;}}}void HuffmanTreeCreat(HuffmanTree &HT){//建立HUFFMAN树int i;int m=2*n-1;int s1,s2;for(i=n;i<m;i++){Select(HT,i-1,&s1,&s2);HT[s1].parent=i;HT[s2].parent=i;HT[s1].sigh=left_child;HT[s2].sigh=right_child;HT[i].weight=HT[s1].weight+HT[s2].weight;}}void HuffmanTreeCode(HuffmanTree HT){//HUFFMAN译码int i;char *temp;temp=(char *)malloc(n*sizeof(char));temp[n-1]='\0';int p;int s;for (i=0;i<n;i++){p=i;s=n-1;while (HT[p].parent!=0){//从结点回溯,左孩子为0,右孩子为1if (HT[p].sigh==left_child)temp[--s]='0';else if (HT[p].sigh==right_child)temp[--s]='1';p=HT[p].parent;}HT[i].code=(char *)malloc((n-s)*sizeof(char));//分配结点码长度的内存空间 strcpy(HT[i].code,temp+s);printf("%s\n",HT[i].code);}}void GetCodingSen(char *sencence){//输入要编码的句子int l;gets(sencence);l=strlen(sencence);sencence[l]='\0';}void HuffmanTreeEncoding(char sen[],HuffmanTree HT){//将句子进行编码int i=0;int j;while(sen[i]!='\0'){for(j=0;j<n;j++){if (HT[j].letter==sen[i]) //字母吻合则用代码取代{strcat(coding,HT[j].code);break;}}i++;if (sen[i]==32) i++;}printf("\n%s",coding);}void HuffmanTreeDecoding(HuffmanTree HT,char code[]){//HUFFMAN译码过程,将代码翻译为句子 char sen[100];char temp[50];char voidstr[]=" ";int i;int j;int t=0;int s=0;for(i=0;i<strlen(code);i++){temp[t++]=code[i];for(j=0;j<n;j++){if (strcmp(HT[j].code,temp)==0){//代码段吻合sen[s]=HT[j].letter;s++;strcpy(temp,voidstr);//将TEMP置空t=0;break;}}}printf("\n%s",sen);}void main(){HTNode hnode;HuffmanTree huff;huff=&hnode;printf("input the letter for coding number\n");scanf("%d",&n);InitTreeNode(huff);HuffmanTreeCreat(huff);HuffmanTreeCode(huff);GetCodingSen(str);HuffmanTreeEncoding(str,huff);。

哈夫曼编码系统代码

哈夫曼编码系统代码

哈夫曼编码系统代码下面是一个简单的哈夫曼编码系统的Python代码示例:```pythonimport heapqfrom collections import defaultdict# 构建哈夫曼树def build_huffman_tree(data):# 统计每个字符的频率freq = defaultdict(int)for char in data:freq[char] += 1# 构建优先队列,按照频率进行排序pq = [[weight, [char, ""]] for char, weight in freq.items()] heapq.heapify(pq)# 合并节点直到只剩一个根节点while len(pq) > 1:lo = heapq.heappop(pq)hi = heapq.heappop(pq)for pair in lo[1:]:pair[1] = '0' + pair[1]for pair in hi[1:]:pair[1] = '1' + pair[1]heapq.heappush(pq, [lo[0] + hi[0]] + lo[1:] + hi[1:]) return pq[0]# 哈夫曼编码def encode(data, huffman_tree):huffman_dict = dict(huffman_tree[1:])encoded_data = ""for char in data:encoded_data += huffman_dict[char]return encoded_data# 哈夫曼解码def decode(encoded_data, huffman_tree):decoded_data = ""node = huffman_treefor bit in encoded_data:if bit == '0':node = node[1]else:node = node[2]if len(node) == 2:decoded_data += node[0]node = huffman_treereturn decoded_data# 测试data = "Hello, world!"huffman_tree = build_huffman_tree(data)encoded_data = encode(data, huffman_tree)decoded_data = decode(encoded_data, huffman_tree)print("原始数据:", data)print("编码后:", encoded_data)print("解码后:", decoded_data)```输出:```原始数据: Hello, world!编码后:000111101011110110011100101010101100011100100000110001 001111解码后: Hello, world!```这个代码演示了如何使用哈夫曼编码对字符串进行压缩和解压缩。

哈夫曼编码算法实现完整版.doc

哈夫曼编码算法实现完整版.doc

哈夫曼编码算法实现完整版.doc
哈夫曼编码(Huffman Coding)是一种编码方式,它通过对最常出现频率最高的字符
串编码最短的字节,以节省带宽和存储空间。

它可以将字符信息编码为变长的序列,最短
的字符占用的位数就更少,而最长的字符占用的位数则更多。

实现哈夫曼编码步骤:
(1)统计字符串中字符出现的次数,并生成频率表
(2)将每个字符对应的频率以及编码长度(未分配)加入一个哈夫曼树(Huffman Tree)的叶节点集合中
(3)将集合中的叶节点按照哈夫曼编码的原则进行排序,并重新构造哈夫曼树
(4)从根节点开始计算叶节点的哈夫曼编码,并以二进制形式记录:找到从根节点
到叶节点的路径,从根节点出发,左子节点编码为0,右子节点编码为1
(5)最终给出每个字符对应的哈夫曼编码
哈夫曼编码有如下特点:
(1)使用有穷自动机原理:利用“最优子结构”和“贪心算法”的原理,构造符合
条件的哈夫曼树,从而获得哈夫曼编码;
(2)信源编码理论:哈夫曼编码是考虑到信源编码理论的一种应用,它能把信源各
字符的分布概率考虑在内,根据信源各字符分布给出较合理的字符编码,使得信源编码长
度最短;
(3)使用哈夫曼编码能更加有效地利用存储空间;
(4)哈夫曼编码能减少网络传输数据量,加快网络传输速度;
(5)哈夫曼编码的解码有较高的效率,可以采用类似BinarySearch的方式进行搜索,时间复杂度可以以O(log n)的速度进行解码
通过使用哈夫曼编码,能使编码的效率更高,节省大量存储空间和带宽。

此外,它的
实现原理相对较为简单,因此,现有大多数编码解码系统都会支持哈夫曼编码。

(完整word版)哈工大数据结构大作业——哈夫曼树生成、编码、遍历

(完整word版)哈工大数据结构大作业——哈夫曼树生成、编码、遍历

一、问题描述1.用户输入字母及其对应的权值,生成哈夫曼树;2.通过最优编码的算法实现,生成字母对应的最优0、1编码;3.先序、中序、后序遍历哈夫曼树,并打印其权值。

二、方法思路1。

哈夫曼树算法的实现§存储结构定义#define n 100 /*叶子树*/#define m 2*(n) –1 /* 结点总数*/typedef struct {/*结点型*/double weight ; /* 权值*/int lchild ;/* 左孩子链*/int rchild ;/* 右孩子链*/int parent; /*双亲链*/ 优点?}HTNODE ;typedef HTNODE HuffmanT[ m ];/*huffman树的静态三叉链表表示*/算法要点1)初始化:将T[0],…T[m—1]共2n-1个结点的三个链域均置空(—1 ),权值为0;2)输入权值:读入n 个叶子的权值存于T的前n 个单元T[0],…T[n],它们是n 个独立的根结点上的权值;3)合并:对森林中的二元树进行n—1次合并,所产生的新结点依次存放在T[i](n〈=i<=m—1)。

每次合并分两步:(1) 在当前森林中的二元树T [0],…T[i—1]所有结点中选取权值最小和次最小的两个根结点T[p1]和T[p2]作为合并对象,这里0<= p1,p2<= i –1;(2) 将根为T[p1]和T[p2]的两株二元树作为左、右子树合并为一株新二元树,新二元树的根结点为T[i]。

即T[p1].parent =T[p2].parent = i ,T[i].lchild= p1, T[i]。

rchild=p2, T[i].weight =T[p1]。

weight + T[p2].weight.2。

用huffman算法求字符集最优编码的算法:1) 使字符集中的每个字符对应一株只有叶结点的二叉树,叶的权值为对应字符的使用频率;2)利用huffman算法来构造一株huffman树;3) 对huffman树上的每个结点,左支附以0,右支附以1(或者相反),则从根到叶的路上的0、1序列就是相应字符的编码Huffman编码实现:存储结构typedef struct{char ch;//存储字符char bits[n+1];//字符编码位串}CodeNode;typedef CodeNode HuffmanCode[n];HuffmanCode H;3。

(完整word版)C语言哈夫曼编码、译码器

(完整word版)C语言哈夫曼编码、译码器

#include <iostream.h>#include <iomanip.h>#include <string.h>#include <malloc.h>#include <stdio.h>//typedef int TElemType;const int UINT_MAX = 1000;typedef struct{int weight;int parent, lchild, rchild;} HTNode, *HuffmanTree;typedef char **HuffmanCode;//-----------全局变量-----------------------HuffmanTree HT;HuffmanCode HC;int *w, i, j, n;char *z;int flag = 0;int numb = 0;// -----------------求赫夫曼编码-----------------------int min(HuffmanTree t, int i){// 函数void select()调用int j, flag;int k = UINT_MAX; // 取k为不小于可能的值for (j = 1; j <= i; j++)if (t[j].weight < k && t[j].parent == 0)k = t[j].weight, flag = j;t[flag].parent = 1;return flag;}//--------------------slect函数----------------------void select(HuffmanTree t, int i, int &s1, int &s2){// s1为最小的两个值中序号小的那个int j;s1 = min(t, i);s2 = min(t, i);if (s1 > s2){j = s1;s1 = s2;s2 = j;}}// --------------算法6.12--------------------------void HuffmanCoding(HuffmanTree &HT, HuffmanCode &HC, int *w, int n){// w存放n个字符的权值(均>0),构造赫夫曼树HT,并求出n个字符的赫夫曼编码HC int m, i, s1, s2, start;//unsigned c,f;int c, f;HuffmanTree p;char *cd;if (n <= 1)return ;//检测结点数是否可以构成树m = 2 * n - 1;HT = (HuffmanTree)malloc((m + 1) *sizeof(HTNode)); // 0号单元未用for (p = HT + 1, i = 1; i <= n; ++i, ++p, ++w){p->weight = *w;p->parent = 0;p->lchild = 0;p->rchild = 0;}for (; i <= m; ++i, ++p)p->parent = 0;for (i = n + 1; i <= m; ++i)// 建赫夫曼树{// 在HT[1~i-1]中选择parent为0且weight最小的两个结点,其序号分别为s1和s2 select(HT, i - 1, s1, s2);HT[s1].parent = HT[s2].parent = i;HT[i].lchild = s1;HT[i].rchild = s2;HT[i].weight = HT[s1].weight + HT[s2].weight;}// 从叶子到根逆向求每个字符的赫夫曼编码HC = (HuffmanCode)malloc((n + 1) *sizeof(char*));// 分配n个字符编码的头指针向量([0]不用)cd = (char*)malloc(n *sizeof(char)); // 分配求编码的工作空间cd[n - 1] = '\0'; // 编码结束符for (i = 1; i <= n; i++){// 逐个字符求赫夫曼编码start = n - 1; // 编码结束符位置for (c = i, f = HT[i].parent; f != 0; c = f, f = HT[f].parent)// 从叶子到根逆向求编码if (HT[f].lchild == c)cd[--start] = '0';elsecd[--start] = '1';HC[i] = (char*)malloc((n - start) *sizeof(char));// 为第i个字符编码分配空间strcpy(HC[i], &cd[start]); // 从cd复制编码(串)到HC}free(cd); // 释放工作空间}//--------------初始化赫夫曼链表---------------------------------void Initialization(){flag = 1;int num;int num2;cout << "下面初始化赫夫曼链表" << endl << "数请输入结点的个n:";cin >> num;n = num;w = (int*)malloc(n *sizeof(int));z = (char*)malloc(n *sizeof(char));cout << "\n请依次输入" << n << "个字符(字符型)\n注意:必须以回车结束:" << endl;char base[2];for (i = 0; i < n; i++){cout << "第" << i + 1 << "个字符:" << endl;gets(base);*(z + i) = *base;for (i = 0; i <= n - 1; i++){cout << setw(6) << *(z + i);}cout << "\n请依次输入" << n << "个权值(\n注意:必须以回车结束):" << endl; for (i = 0; i <= n - 1; i++){cout << endl << "第" << i + 1 << "个字符的权值:";cin >> num2;*(w + i) = num2;}HuffmanCoding(HT, HC, w, n);//------------------------打印编码-------------------------------------------cout << "字符对应的编码为:" << endl;for (i = 1; i <= n; i++){//cout<<"字符"<<*(z+i-1)<<"的编码";puts(HC[i]);}//--------------------------将赫夫曼编码写入文件------------------------cout << "下面将赫夫曼编码写入文件" << endl << "...................." << endl; FILE *htmTree;char r[] =' ', '\0'};if ((htmTree = fopen("htmTree.txt", "w")) == NULL){cout << "can not open file" << endl;return ;}fputs(z, htmTree);for (i = 0; i < n + 1; i++){fprintf(htmTree, "%6d", *(w + i));fputs(r, htmTree);}for (i = 1; i <= n; i++){fputs(HC[i], htmTree);fputs(r, htmTree);}fclose(htmTree);cout << "已将字符与对应编码写入根目录下文件htmTree.txt中" << endl << endl; }//---------------------获取报文并写入文件---------------------------------void InputCode()//cout<<"请输入你想要编码的字符"<<endl;FILE *tobetran;char str[100];if ((tobetran = fopen("tobetran.txt", "w")) == NULL){cout << "不能打开文件" << endl;return ;}cout << "请输入你想要编码的字符" << endl;gets(str);fputs(str, tobetran);cout << "获取报文成功" << endl;fclose(tobetran);}//---------------------编码函数---------------------------------void Encoding(){cout << "下面对目录下文件tobetran.txt中的字符进行编码" << endl; FILE *tobetran, *codefile;if ((tobetran = fopen("tobetran.txt", "rb")) == NULL){cout << "不能打开文件" << endl;}if ((codefile = fopen("codefile.txt", "wb")) == NULL) {cout << "不能打开文件" << endl;}char *tran;i = 99;tran = (char*)malloc(100 *sizeof(char));while (i == 99){if (fgets(tran, 100, tobetran) == NULL){cout << "不能打开文件" << endl;break;}for (i = 0; *(tran + i) != '\0'; i++){for (j = 0; j <= n; j++){if (*(z + j - 1) == *(tran + i)){fputs(HC[j], codefile);if (j > n){cout << "字符错误,无法编码!" << endl;break;}}}}}cout << "编码工作完成" << endl << "编码写入目录下的codefile.txt中" << endl << endl;fclose(tobetran);fclose(codefile);free(tran);}//-----------------译码函数---------------------------------void Decoding(){cout << "下面对根目录下文件codefile.txt中的字符进行译码" << endl;FILE *codef, *txtfile;if ((txtfile = fopen("Textfile.txt", "w")) == NULL){cout << "不能打开文件" << endl;}//txtfile=fopen("Textfile.txt","w");if ((codef = fopen("codefile.txt", "r")) == NULL){cout << "不能打开文件" << endl;}//codef=fopen("codefile.txt","r");char *work, *work2, i2;int i4 = 0, i, i3;unsigned long length = 10000;work = (char*)malloc(length *sizeof(char)); fgets(work, length, codef);work2 = (char*)malloc(length *sizeof(char)); i3 = 2 * n - 1;for (i = 0; *(work + i - 1) != '\0'; i++){i2 = *(work + i);if (HT[i3].lchild == 0){*(work2 + i4) = *(z + i3 - 1);i4++;i3 = 2 * n - 1;i--;}else if (i2 == '0')i3 = HT[i3].lchild;i3 = HT[i3].rchild;}*(work2 + i4) = '\0';fputs(work2, txtfile);cout << "译码完成" << endl << "内容写入根目录下的文件txtfile.txt中" << endl << endl;cout << work2;free(work);free(work2);fclose(txtfile);fclose(codef);}//------------------------打印赫夫曼树的函数-----------------------void coprint(HuffmanTree start, HuffmanTree HT){if (start != HT){FILE *TreePrint;if ((TreePrint = fopen("TreePrint.txt", "a")) == NULL){cout << "创建文件失败" << endl;return ;numb++; //该变量为已被声明为全局变量coprint(HT + start->rchild, HT);cout << setw(5 *numb) << start->weight << endl;fprintf(TreePrint, "%d\n", start->weight);coprint(HT + start->lchild, HT);numb--;fclose(TreePrint);}}void Tree_printing(HuffmanTree HT, int w){HuffmanTree p;p = HT + w;cout << "下面打印赫夫曼树" << endl;coprint(p, HT);cout << "打印工作结束" << endl;}//------------------------主函数------------------------------------void main(){char choice;cout << " 赫夫曼编码解码系统" << endl;cout << "1.要初始化赫夫曼链表请输入'i'" << endl;cout << "2.要编码请输入'e'" << endl;cout << "3.要译码请输入'd'" << endl;cout << "4.要打印编码请输入'p'" << endl;cout << "5.要打印赫夫曼树请输入't'" << endl;cout << "6.要离开请输入'q'" << endl;// if(flag==0)cout<<"\n请先初始化赫夫曼链表,输入'i'"<<endl; cin >> choice;switch (choice){case 'i':Initialization();break;case 'w':InputCode();break;case 'e':Encoding();break;Decoding();break;case 't':Tree_printing(HT, 2 *n - 1);break;case 'q':default:cout << "input error" << endl;}}free(z);free(w);free(HT);}运行结果:赫夫曼编码解码系统1.要初始化赫夫曼链表请输入'i'2.要编码请输入'e'3.要译码请输入'd'4.要打印编码请输入'p'5.要打印赫夫曼树请输入't'6.要离开请输入'q'下面初始化赫夫曼链表数请输入结点的个n:8请依次输入8个字符(字符型)注意:必须以回车结束:第1个字符:a第2个字符:b第3个字符:c第4个字符:d第5个字符:e第6个字符:f第7个字符:g第8个字符:ha b c d e f g h 请依次输入8个权值(注意:必须以回车结束):第1个字符的权值:5第2个字符的权值:29第3个字符的权值:7第4个字符的权值:8第5个字符的权值:14第6个字符的权值:23第7个字符的权值:3第8个字符的权值:11字符对应的编码为:01101011101111110000111010下面将赫夫曼编码写入文件....................已将字符与对应编码写入根目录下文件htmTree.txt中赫夫曼编码解码系统1.要初始化赫夫曼链表请输入'i'2.要编码请输入'e'3.要译码请输入'd'4.要打印编码请输入'p'5.要打印赫夫曼树请输入't'6.要离开请输入'q'i下面初始化赫夫曼链表数请输入结点的个n:27请依次输入27个字符(字符型)注意:必须以回车结束:第1个字符:第2个字符:a第3个字符:b第4个字符:c第5个字符:d第6个字符:第7个字符: f第8个字符: g第9个字符: h第10个字符: i第11个字符: j第12个字符: k第13个字符: l第14个字符: m第15个字符: n第16个字符: o第17个字符: p第19个字符:r第20个字符:s第21个字符:t第22个字符:u第23个字符:v第24个字符:w第25个字符:x第26个字符:y第27个字符:za b c d e f gm n o p q r s t z请依次输入27个权值(第1个字符的权值:186第2个字符的权值:64第3个字符的权值:13第4个字符的权值:22第5个字符的权值:32第6个字符的权值:103第7个字符的权值:21第8个字符的权值:15第9个字符的权值:47第10个字符的权值:57第11个字符的权值:1第12个字符的权值:5第13个字符的权值:32第14个字符的权值:20第15个字符的权值:57第16个字符的权值:63第17个字符的权值:15第18个字符的权值:1第19个字符的权值:48第20个字符的权值:51第21个字符的权值:80第22个字符的权值:23第23个字符的权值:8第24个字符的权值:18第25个字符的权值:1第26个字符的权值:16第27个字符的权值:1字符对应的编码为: 11010101001000001010110010111110100101000001101111011100111101101011111111101111000100110111101110100100011111000011111101011110011110111101001111111011111下面将赫夫曼编码写入文件....................已将字符与对应编码写入根目录下文件htmTree.txt中。

数据结构之哈夫曼编码和解码C源代码

数据结构之哈夫曼编码和解码C源代码

玩转算法与数据结构之哈夫曼编码和解码—HIT2000鲁天伟二叉树的一个很重要的应用是生成哈夫曼树来完成哈夫曼编码和解码。

哈夫曼树:假设一个字符串中只有'A','B','C','D','E','F','G'这七个字符,这七个字符出现的权值(也就是出现次数)是3,5,7,6,5,9,8。

我们就以这个字符串作为样本,来进行字符编码,将字符映射成一串二进制码(比如’A’对应000,‘B’对应001),那么最终整个字符串将被编码成一长串二进制码。

我们生成哈夫曼树来进行编码,如下图1所展示就是哈夫曼树最终的模样。

哈夫曼树算法:使用字符数组{'A','B','C','D','E','F','G'},对就权值数组{3,5,7,6,5,9,8};1、我们先从权值数组左边开始,找到数组中未打过使用标记的最小数p和次小数q,以p+q作父结点,p作为左子结点,q作为右子结点。

原则是右子结点权值大于或等于左子结点权值。

把p和q的权值数组位置打标记已使用过,父结点p+q作为新的权值加入到权值数组尾部。

(此例中第一次执行p=3和q=5,对应字符‘A’和‘B’。

把这两个数相加得8,形成新的结点作为父结点。

3作为左子结点,5作为右子结点。

把3和5的权值数组位置打标记已使用过。

父结点权值8作为新的权值加入到权值数组尾部。

)2、重复步骤1,如果叶子结点有N个,那么进行N-1次合并,可以建成哈夫曼树。

图表 1 哈夫曼树编码算法:如上图1所示,所有的字符都出现在叶子结点的位置,从根结点开始遍历,查找每个叶子结点的字符,根到每个叶子结点只有一条路,从根开始向左走标0,向右走标1,根据查找路线,我们可以得出每个叶子结点字符的二进制编码串。

哈夫曼编码译码器代码及运行图示

哈夫曼编码译码器代码及运行图示
printf("按Enter继续:\t Input Enter to continue:\n");
ch=getchar();
while(ch!='q') /*当键入’q’时程序运行结束*/
{Explain();
while(ch!='r'&&ch!='c'&&ch!='e'&&ch!='d'&&ch!='q')
typedef char * *HuffmanCode;
/*函数声明*/
void readdata(elemtype *w);/*读取字符信息*/
huffmantree createhuff(elemtype *w);/*建立哈弗曼树*/
char * *huffmancode(huffmantree ht);/*哈弗曼编码*/
w[24].data='x' ;w[25].data='y' ;
w[26].data='z' ;
printf("If you input new char weight yourself y/n:\t是否自己输入字符频度y/n:\n");
zf=getchar();
while(zf!='n'&&zf!='y'&&zf!='q')
p->weight=w->weight;
}
else
{p->data='\0';
p->weight=0;

(完整word版)数据结构课程设计哈夫曼编码111

(完整word版)数据结构课程设计哈夫曼编码111

《数据结构与算法》课程设计(2009/2010学年第二学期第20周)指导教师:班级:计算机科学与技术学号:姓名:《数据结构与算法》课程设计目录一、前言1.摘要2.《数据结构与算法》课程设计任务书二、实验目的三、题目--赫夫曼编码/译码器1.问题描述2.基本要求3.测试要求4.实现提示四、需求分析--具体要求五、概要设计六、程序说明七、详细设计八、实验心得与体会前言1.摘要随着计算机的普遍应用与日益发展,其应用早已不局限于简单的数值运算,而涉及到问题的分析、数据结构框架的设计以及设计最短路线等复杂的非数值处理和操作。

算法与数据结构的学习就是为以后利用计算机资源高效地开发非数值处理的计算机程序打下坚实的理论、方法和技术基础。

算法与数据结构旨在分析研究计算机加工的数据对象的特性,以便选择适当的数据结构和存储结构,从而使建立在其上的解决问题的算法达到最优。

数据结构是在整个计算机科学与技术领域上广泛被使用的术语。

它用来反映一个数据的内部构成,即一个数据由那些成分数据构成,以什么方式构成,呈什么结构。

数据结构有逻辑上的数据结构和物理上的数据结构之分。

逻辑上的数据结构反映成分数据之间的逻辑关系,而物理上的数据结构反映成分数据在计算机内部的存储安排。

数据结构是数据存在的形式。

《数据结构》主要介绍一些最常用的数据结构,阐明各种数据结构内在的逻辑关系,讨论其在计算机中的存储表示,以及在其上进行各种运算时的实现算法,并对算法的效率进行简单的分析和讨论。

数据结构是介于数学、计算机软件和计算机硬件之间的一门计算机专业的核心课程,它是计算机程序设计、数据库、操作系统、编译原理及人工智能等的重要基础,广泛的应用于信息学、系统工程等各种领域。

学习数据结构是为了将实际问题中所涉及的对象在计算机中表示出来并对它们进行处理。

通过课程设计可以提高学生的思维能力,促进学生的综合应用能力和专业素质的提高。

2.《数据结构与算法》课程设计任务书《数据结构与算法》是计算机专业重要的核心课程之一,在计算机专业的学习过程中占有非常重要的地位。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

#include <stdio.h>#include <stdlib.h>#include <math.h>#include <string.h>#define N 1000char kind[N]={'\0'};int num[N]={0};int count=0;int s1,s2;typedef struct{int weight; /*字符权重*/int parent,lchild,rchild;}HTNode,*HuffmanTree; /*定义哈夫曼树结点*/ typedef char **HuffmanCode;struct charcode{char data;char code[20];}Code[N],d[N],e[N];void Creat_message() /*输入字符并存入文件*/{FILE *fp;char c;晩?灦昽灯湥尨文本文件.txt,wb))==NULL){printf(cannot open this file!\n);return ;}牰湩晴尨请输入原代码,以'#'表示结束\n);do{scanf(%c,&c);fputc(c,fp);}while (c!='#');fclose(fp);}void Calculate() /*计算文件中字符的权值*/ {char c;int i=1,k;FILE *fp;晩?灦昽灯湥尨文本文件.txt,b))==NULL){printf(cannot open this file\n);return ;}c=fgetc(fp);while(c!='#'){for (k=0;k<i;k++)if(c==kind[k]){num[k]++;break;}if(k>=i&&kind[k-1]!=c){kind[i]=c;num[i]++;i++;}c=fgetc(fp);}count=i-1;}void select(HuffmanTree Hu,int j) /*寻找输入的字符数据中权值最小的两个结点*/ {int k=1,t;while(Hu[k].parent!=0) k++;for(t=k;t<=j;t++)if(Hu[t].parent==0 && Hu[t].weight<Hu[k].weight)k=t;s1=k;k=1;while(Hu[k].parent!=0 ||k==s1) k++;for(t=k;t<=j;t++)if(Hu[t].weight<Hu[k].weight && Hu[t].parent==0 &&t!=s1)k=t;s2=k;}void HuffmanCoding () /*构建哈夫曼树并编码*/{void select(HuffmanTree Hu,int j);HuffmanTree HT;HuffmanCode HC;int m,i,start,f,c;char *cd;FILE *fp;if (count<=1) return;m=2*count-1;HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode));for(i=1;i<=count;i++)HT[i].weight=num[i];for(i=1;i<=m;i++){HT[i].parent=0;HT[i].lchild=0;HT[i].rchild=0;}for(i=count+1;i<=m;i++){select(HT,i-1);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;}HC=(HuffmanCode)malloc((count+1)*sizeof(char*));cd=(char*)malloc(count*sizeof(char));cd[count-1]='\0';for(i=1;i<=count;i++){start=count-1;for(c=i,f=HT[i].parent;f!=0;c=f,f=HT[f].parent)if (HT[f].lchild==c) cd[--start]='0';else cd[--start]='1';HC[i]=(char*)malloc((count-start)*sizeof(char)); strcpy(HC[i],&cd[start]);}晩?灦昽灯湥尨字符代码.txt,wb))==NULL){printf(cannot open this file\n);return ;}for(i=1;i<=count;i++){Code[i].data= kind[i];strcpy(Code[i].code,HC[i]);fwrite(&Code[i],sizeof(struct charcode),1,fp);}fclose(fp);}void Transform() /*将字符文件翻译成代码文件*/ {FILE *fp1,*fp2,*fp3;int i;char c;晩?灦?潦数?字符代码.txt,b))==NULL){printf(cannot open this file\n);return ;}晩?灦?潦数?文本文件.txt,b))==NULL){printf(cannot open this file\n);return ;}晩?灦?潦数?码本文件.txt,wb))==NULL){ printf(cannot open this file\n);return ;}for(i=0;i<count;i++)fread(&d[i],sizeof(struct charcode),1,fp1);while(!feof(fp2)){c=fgetc(fp2);for(i=0;i<count;i++)if(d[i].data==c){fputs(d[i].code,fp3);break;}}fputc('#',fp3);fclose(fp3);}void Translate() /*将代码文件翻译成字符文件*/ {FILE *fp1,*fp2,*fp3;int i,j,k;char c[20]={'\0'};晩?灦?潦数?码本文件.txt,b))==NULL){printf(cannot open this file\n);return ;}晩?灦?潦数?字符代码.txt,b))==NULL){printf(cannot open this file\n);return ;}晩?灦?潦数?破译文件.txt,wb))==NULL){printf(cannot open this file\n);return ;}for(i=1;i<=count;i++)fread(&d[i],sizeof(struct charcode),1,fp2);i=0;c[i]=fgetc(fp1);while(c[i]!='#'){for(k=1;k<=count;k++)if(!strcmp(c,d[k].code)){fputc(d[k].data,fp3);for(j=0;j<=i;j++) c[j]='\0';i=-1;break;}i++;c[i]=fgetc(fp1);}fputc('#',fp3);fclose(fp1);fclose(fp2);fclose(fp3);}void print1(char *name) /*打印文件函数*/ {FILE *fp;char c;if((fp=fopen(name,b))==NULL){printf(cannot open this file\n);return ;}c=fgetc(fp);while(c!='#'){printf(%c,c);c=fgetc(fp);}}void print2(char *name) /*打印文件函数*/ {FILE *fp;int i=1;if((fp=fopen(name,b))==NULL){printf(cannot open this file\n);return ;}while(!feof(fp)){fread(&e[i],sizeof(struct charcode),1,fp);printf(%c--%s\n,e[i].data,e[i].code);i++;}}void main(){Creat_message();牰湩晴尨您输入的文本文件是:\n);牰湩?尨文本文件.txt);printf(\);Calculate();HuffmanCoding ();牰湩晴尨每个字符相应的哈夫曼编码是:\n);牰湩?尨字符代码.txt);printf(\);Transform();牰湩晴尨原文件的码本文件(即全为字符编码)为:\n);牰湩?尨码本文件.txt);printf(\);Translate();牰湩晴尨用码本文件和字符代码求出的破译文件为:\n); 牰湩?尨破译文件.txt);printf(\);}。

相关文档
最新文档