https://www.myziyuan.com/
- 00萨满祭司00
- #include #include #include #define m 1000 //定义字符串最大长度#define n 128 //定义叶节点编号typedef struct节点//定义hafman树节点结构{int重量; struct节点* lchild,* rchild,*父级; //指向左子,右子,和双重节点结构节点*下一步; //指向创建的hafman树的下一个节点} hfmnode,* hfmtree; typedef struct ////定义结构{char ch; //存储相应的字符char代码[n + 1]; //存储相应字符的编码int开始位置; //将编码的起始位置存储} CodeNode; int n; //存储多个void clearscreen(){system(“cls”)(“cls”)/ / /} void打开(char s [])//打开存储的字符或编码文件,将它放在字符数组中{char name.[10];文件* fp; INT i = 0; printf(“请输入您要打开的文件名:”);得到(姓名); //打开文件名if((fp = fopen(name,nr))== null){printf(“打开失败!\ n”); //如果打开失败,退出退出(1);} s [i ++] = fgetc(fp);而(S [I-1]!= eof)S [i ++] = FGETC(FP); s [i] ='\ 0'; //访问字符串结束fclose(fp); void保存(char s [])//保存字符或编码到文件{char名[10];文件* fp; printf(“请输入要保存的文件名:”);得到(姓名);如果fp = fopen(名称,“wt”))== null){printf(“存储失败!”);退出(1);}肉类(S,FP); printf(“\ n椎间盘,文件名:%s。\ n”,name); printf(“\ n按Enter继续......”); getchar(); fclose(fp);} void searchstr(char s [],char str [],int count []){//找到n字符串中的字符umber和int i,j,k = 0的次数; for(i = 0; inext)if(p-> weightparent == 0){min = p->重量; * ht1 = p;} min = 32767; for(i = 0,p = ht; inext)if(p-> weightparent == 0 && p!= * ht1)//命令第二个小节点不等于第一节点{min = p->权重; * ht2 = p;}} void creatfmtree(hfmtree * ht,int count []){//创建Hafman树Int i; HFMTree P,HT1,HT2; // ht1,ht2存储值的最小和小节点的位置,分别p = * ht =(hfmtree)malloc(hfmnode)); p-> next = p-> lchild = p-> rchild = p->父= null; //初始化haffmann表并具有2n-1节点(i = 1; inext =(hfmtree)malloc(hfmnode)); p = p-> next; p-> next = p-> lchild = p-> rchild = p->父= null;}(i = 0,p = * ht; iweight = count [i]; p = p-> next;} for(i = n; iparent = ht2->父= p; p-> lchild = ht1; p-> RCHILD = HT2; P->重量= HT1 - >重量+ HT2->权重; //在最后一个节点P->下一个节点中放置两个节点的重量; // p指向没有存储权重的下一个节点}} void hfmcode hfmtree ht,codenode hc [],char str []){//从每个叶节点开始,使用Havman树编码每个角色,最后构建一个Hafmanou int i; hfmtree q,p = ht; for(i = 0; iParent; q = q->父级)//判断q由q指向的节点,左子组设置0,右子组合1 if(q == q->父 - > lchild)hc [i] .code [ - hc [i] .start] ='0';否则hc [i] .code [ - hc [i] .start] ='1'; p = p-> next; //判断下一个叶节点} void totnoding(char s [],CodeNode HC [],Char代码[]){// UtilizationHawman代码表对i,j;代码[0] ='\ 0'; //代码数组初始化(i = 0; s [i]; i ++)//每个字符在Hawman编码表中的相应编码中的相应编码存储在存储的总编码中(j = 0; jparent; root = root->父母); //指向hafman树的根节点,带有根(i = 0,p = root;代码[i]; i ++)//从根节点开始访问树{if(代码[i] == '0')p = p-> lchild;否则p = p - > rchild; if(p-> lchild == null && p-> rchild == null)//当节点输出时{for(j = 0,q = ht; q!= = p; q)= q-> next,j ++); s [k ++] = str [j]; p = root; //缩回到根节点}} s [k] ='\ 0'; //解码完成,在字符串中,最后一个单位存储在'\ 0'} void编码(char s“,char str [],char code [],int Count中T [],HFMTree * HT,CodeNode HC []){ClearScreen(); printf(“\ n打开字符串的文件... \ n \ n”);开放; //打开源代码文件searchstr(s,str,count); //在字符串中查找不同的字符及其外观reathfmtree(ht,count); //使用每个字符的Hafman树HFmcode(* HT,HC,STR)的次数进行叶子的重量; //使用Hawman树对每个叶节点进行编码,在编码表中存入总计(S,HC,代码); //使用编码表最后编码printf的字符串(“字符串中的”\ n读取:\ n“);投入; printf(“\ n”最终的hawman代码是:\ n“)放置(代码); printf(”\ n保存编码“);保存(代码); //保存最终的Hawman代码} void转码(Char代码[],char str [],char ss [],hfmtreE * HT,CodeNode HC []){ClearScreen(); printf(“\ n打开编码文件... \ n \ n”);打开(代码); //打开代码文件解码(代码,* ht,str,ss); //解码编码以将ss []存储在字符串阵列ss [] printf中(“\ n最终字符串为:\ n”);投放(SS); printf(“\ n保存编码”);保存(SS); //保存解码的字符串} void main(){// main function char s [m],ss [m]; //定义字符串数组,s []存储字符串,ss [],ss [],ss [n]; //存储n不同的字符int count [n]; //存储原始字符中的n个不同的字符,字符串中出现的字符数[m]; //在最终编码后存储编码的CHAR选项; hfmtree ht; //定义Hawman Tree CodeNode HC [N]的链表; //定义一系列Hafman编码表s,存储与每个字符对应的Hafman代码,do {clearscreen(); printf(“\ n \ n”); printf(“*** ******** hawman tree ************* \ n”); printf(“** ** \ n”); printf(“** 1.)。** \ n”); printf(“** 2.解码。** \ n”); printf(“** 0.退出。** \ n”); printf(“** ** \ n”); printf(“** ** \ n”); printf(“** ** \ n”); printf(“**请输入序列号的数量(0-2)** \ n”); Printf(“*********************************** \ n”); scanf(“%c”,&选择)getchar();切换(选择){案例'1':编码(s,str,代码,计数,ht,hc);休息; //代码案例'2':转码(代码,str,ss,&ht,hc);休息; //解码案例'0':中断;默认值:printf(“输入错误!请重新输入!\ n”);}} while(选择!='0')}
- 2021-07-03 01:42:21
- 好牛通
- 注意非常详细,我希望为您提供帮助! #ifndef huffman_tree_h#define huffman_tree_h#endif#include typedef struct {unsigned Int重量; unsigned int父,lchild,rchild;} htnode,* huffmantree; //节点类型存储在霍夫曼树typedef char * * huffmancode; //将字符串S2复制到S1 i = 0;而(S2 [i]!='\ 0'){s1 [i] = s2 [i]; i ++;} s1 [i] ='\ 0';} void选择(huffmantree ht,int t,int&s1,int&s2){//在ht [1]中到ht [t-1]到找到两个S1和S2 I = 1,S1 = S2 = 0; ht [0] .weight = 65535;而(i <= t ){ //遍历查找权值最小的结点S1 if( HT[i].parent == 0 && HT[i].weight < HT[s1].weight ) s1 = i; i++; } i = 1; while( i <= t ){ //遍历查找除S1外权值最小的结点S2 if( i != s1 && HT[i].parent == 0 && HT[i].weight < HT[s2].weight ) s2 = i; i++; }}int HuffmanCoding( HuffmanTree &HT,HuffmanCode &HC,int *w,int n){ //根据各个字符的权值构造赫夫曼树HT,将对应的赫夫曼编码存储在HC中 int s1,s2,m,i,start; unsigned int c,f; HTNode * p; char *cd; if( n <= 1 ) return 0; m = 2 * n - 1; //赫夫曼树的总结点树为m HT = (HuffmanTree)malloc((m + 1) * sizeof(HTNode)); //申请存储赫夫曼树的空间 for(p = HT + 1, i = 1; i <= n; ++i, ++p, ++w){ //将各个叶子结点的weight赋以相应的权值,parent,lchild,rchild均赋为0 p->重量= *(w + 1); p->父= p-> lchild = p-> rchild = 0;} for(; i <= m; ++i, ++p ){ //将各个非叶子结点的weight,parent,lchild,rchild均赋为0 p->权重= p->父= p-> lchild = p-> rchild = 0} for(i = n + 1; i <= m; ++i ){ //构造赫夫曼树,给各个非叶子结点赋值 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; } HC = (HuffmanCode)malloc((n + 1) * sizeof(char *)); //申请空间,用于存储指向存储各个字符相应赫夫曼编码的字符数组的指针 cd = (char *)malloc(n * sizeof(char)); //申请用于求赫夫曼编码 cd[n - 1] = '\0'; //编码结束符 for( i = 1; i <= n; ++i){ //逐个字符求赫夫曼编码 start = n -1; //编码在数组cd[]中的最前位置 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)); //为第i个字符编码分配空间 strcpy(HC[i], &cd[start]); //将cd[]数组的start位置到n-1位置复制给HC[i] } free(cd); //释放空间 return 1;}以上为第一部分#include #include #include“huffman_tree.h”#define是1 //当程序被称为INItialization Hafman树或已从HTFtree文件中读取,将init_mode设置为yes,否则否#定义no 0void inithuff_t(huffmantree&ht,huffmancode&hc,char ch [],int&n){//初始化herman的号码,需要用户输入字符和相应的权重I = 1,W [100],TEM,J;字符[20];文件*保存; printf(“请输入编码字符集n:”的大小); scanf(“%d”,&n); //获取用户设置的字符数(i <= n){//获取字符和用户的相应权重,分别存储在CH []和W []阵列中,“请输入值第一个字符和角色的值,i); fflush(stdin); fflush(stdin); scanf(“%c%d”,&ch [i],&w [i]);一世++;} ch [i] ='\ 0'; huffmancoding(ht,hc,w,n); //根据用户输入,生成hafmanns和与herffman编码对应的每个字符,现有的如果在ht树和hc中存在((保存= fopen(“htftree”,“w”))== null){//打开文件printf (赫菲尔曼树的“打开文件失败... \ n”);退出(0);} tem = n; //接下来的14行被转换为字符中的字符写入文件j = 0; (TEM!= 0){TEM = TEM / 10; J ++;} tem = n; a [j] ='\ 0'; (TEM!= 0){a [j - 1] =(char)(tem%10 + 48); TEM = TEM / 10; j - ;} f(a,save); printf(“%d \ n”,n); //屏幕输出字符集大小n fputc('\ n',保存); for(i = 1; i <= n; i ++){//每个字符的输出和相应的Herffman编码fputc(ch [i],保存); printf(“%c \ t”,ch [i]); fputc('\ t',保存);呕吐(HC [I],保存); printf(“%s \ n”,hc [i]); fputc('\ n',save); for(i = 1; i <= 2 * n - 1; i ++){//写下Herffmann树的每个节点的父,lchild,rchild,tem = ht [i] .parent; //将i节点的父节点转换为字符并写入文件(tem == 0){fputc(tem + 48,保存); fputc('',保存);} else {j = 0;虽然(tem!= 0){tem = tem / 10 j ++;} tem = ht [i] .parent; a [j] ='\ 0'; (TEM!= 0){a [j - 1] =(char)(tem%10 + 48); TEM = TEM / 10; j-;}肉(a,保存); fputc('',保存);} tem = ht [i] .lchild; //将i节点的Lchild转换为字符,并写入if(tem == 0){fputc(tem + 48,保存); fputc('',保存);} else {j = 0; (TEM!= 0){TEM = TEM / 10; J ++; tem = ht [i] .lchild; a [j] ='\ 0'; (TEM!= 0){a [j - 1] =(char)(tem%10 + 48); TEM = TEM / 10; j - ;} fpuTS(a,保存); fputc('',保存);} tem = ht [i] .rchild; //将I节点的RCHILD转换为字符,并且如果(tem == 0){fputc(tem + 48,保存); fputc('\ n',save)} els {j = 0; (TEM!= 0){TEM = TEM / 10; j ++; tem = ht [i] .rchild; a [j] ='\ 0'; (TEM!= 0){a [j - 1] =(char)(tem%10 + 48); TEM = TEM / 10; j - ;} f(a,save); fputc('\ n',保存); fclose(保存); void编码(huffmantree&ht,huffmancode&hc,char ch []){//取决于掌握在文件中指定的用户中的字符的Herffmann进入相应的编码,将生成的编码存储到用户指定的文件文件* tobetran,* codefile; char tobetran_name [100],codefile_name [100]; //存储文件名INT I; Char C; printf(“请输入文件的文件名想要对文件进行编码:“)Scanf(”%s“,tobetran_name); //获取文件名是否要编码文件(tobetran_name,”r“))== null){//打开文件printf (“打开文件失败...... \ n”);退出(0); printf(“请在编码后输入存储的文件存储的文件名:”); scanf(“%s” ,codefile_name); //文件名如果由编码编码指示的编码编码的编码的文件存储(codefile_name,“w”)== null){//打开文件printf(“打开文件失败... \ n“);退出(0);} c = fgetc(tobetran); //从文件(c!= eof){////代码文件中的各个字符,读取一个字符,直到文件结束i = 1;而(c!= ch [i] && ch [i]!='\ 0')//从从文件读取的文件中的文件中查找,在ch []数组字符i ++中;一世f(ch [i] =='\ 0'){//找不到,c不在ch []阵列中,c无法识别,程序错误,退出printf(“字符%c无法识别,程序将退出。\ n“,c);退出(0);} f(HC [i],Codefile); //如果找到它,将相应的Herffmann代码写入文件中的文件(“%s”,hc [i]); //将CA对应的Herffman代码输出到屏幕C = FGETC(FGETHAN); //读入文件中的下一个字符} printf(“\ n”); fclose(Fobetran); fclose(codefile); void解码(huffmantree ht,char ch [],int n){//通过Herffmann编码,翻译成相应的字符解码指定的文件,将其转换为相应的字符,并将其存储到指定的文件int p,i = 1; char代码[1000],char codefile_name [100],textfile_name [100]; //存储文件名p =2 * n - 1;文件* codefile,* textfile; printf(“请输入要翻译的文件名:”); scanf(“%s”,codefile_name); //获取文件名((CodeFile = Fopen,“R”))== null){//打开文件printf(“打开文件失败... \ n”);退出(0);} printf(“请输入翻译字符存储的文件的文件名:”); scanf(“%s”,textfile_name); //获取文件名(textfile_name,“w”)== null)存储文件名(textfile_name,“)== null){//打开文件printf(”打开文件失败.... .. \ n“ );退出(0);} C = FGETC(CODEFILE);而(c!= eof){code [i] = c; I ++; c = fgetc(Codefile);代码[i] ='\ 0'; //从文件读取字符,存储在代码[]数组i = 1;而(代码[i]!='\ 0'&& p!= 0){//对齐代码[] Herffma编码用于解码if(代码[i] =='0')p = ht [p] .lchild; //输入左分支else p = ht [p] .rchild; //如果(!ht [p] .lchild &&!ht [p] .rchild){//输入叶节点fputc(ch [p],textfile; //将相应的字符写入文件printf( “%c”,ch [p]); //将相应的字符输出到屏幕p = 2 * n - 1; //从根} i ++的根部重新解码;} printf(“ \ n“); void readhuff_t(huffmantree&ht,huffmancode&hc,char ch [],int&n){//从文件读取Herffmann文件* htftree; char c [100],ch1; int i,j ,t;如果((htftree = fopen(“htftree = fopen(”htftree“,”r“))== null){//打开与Herffman树信息Printf(”打开文件失败... \ n“);退出(0) fgets(c,10,htftree); //获取字符串表示的数量Herffmann离开节点i = 0; //以下6行将字符串转换为IntegeQuiry形式为什么(C [i]!='\ n')i ++; n = 0; for(j = 0; j
- 2021-07-03 01:40:35
- nij
- 哈夫曼编/译码系统的主要思想,1、是一种利用二叉树实现的编码原理霍夫曼(Huffman)编码原理 霍夫曼(Huffman)编码是1952年为文本文件而建立,是一种统计编码。属于无损压缩编码。 霍夫曼编码的码长是变化的,对于出现频率高的信息,编码的长度较短;而对于出现频率低的信息,编码长度较长。这样,处理全部信息的总码长一定小于实际信息的符号长度。
- 2021-07-03 01:40:35