資料結構——哈夫曼樹的應用
阿新 • • 發佈:2018-11-28
Huffman樹的應用1
#include<stdio.h> #include<stdlib.h> #include<string.h> #define N 6 #define M 2*N-1 #define MAXINT 32767 #define ch 30 #define NUM 100 typedef char numcode[NUM]; typedef char charcode[ch]; typedef char* HuffmanCode[N] ; typedef struct{ int weight; //權值 int parent; //雙親 int lchild; //左孩子 int rchild; //右孩子 }HTNode,HuffmanTree[M]; void select(HuffmanTree ht,int pos,int *s1,int *s2){ //選擇最小值與次小值 int i,j,m1,m2;/*m1存放最小權值,s1是m1在陣列的下標*/ m1=m2=MAXINT;/*m2存放次小權值,s2是m2在陣列的下標*/ for(j=0;j<=pos;j++) { if(ht[j].weight<m1&&ht[j].parent==-1){ /*是否出現新的最小值*/ m2=m1; *s2=*s1; *s1=j; m1=ht[j].weight; } else if(ht[j].weight<m2&&ht[j].parent==-1){ /*是否出現新的次小值*/ m2=ht[j].weight; *s2=j; } } } void CrtHuffmanTree(HuffmanTree ht,int w[]){ //建立哈夫曼樹 int i,s1,s2; for(i=0;i<N;i++){ //葉子初始化 ht[i].weight=w[i]; ht[i].parent=-1; ht[i].lchild=-1; ht[i].rchild=-1; } for(i=N;i<M;i++){ //其他結點初始化 ht[i].weight=0; ht[i].parent=-1; ht[i].lchild=-1; ht[i].rchild=-1; } /*選擇合併*/ for(i=N;i<M;i++) { select(ht,i-1,&s1,&s2); /*選擇最小的兩項*/ ht[i].weight=ht[s1].weight+ht[s2].weight; ht[s1].parent=i; ht[s2].parent=i; ht[i].lchild=s1; ht[i].rchild=s2; } } void CrtHuffmanCode(HuffmanTree ht,HuffmanCode hc){ //建立字元編碼集 char *cd=(char*)malloc(N*sizeof(char));; int start,c,p,i; cd[N-1]='\0'; for(i=0;i<N;i++){ start=N-1; c=i; p=ht[i].parent; while(p!=-1){ --start; if(ht[p].lchild==c) cd[start]='0'; else cd[start]='1'; c=p; p=ht[p].parent; } hc[i]=(char*)malloc((N-start)*sizeof(char)); strcpy(hc[i],&cd[start]); } free(cd); } void printcode(char s[],HuffmanCode hc){ //輸出個字元及對應編碼 for(int i=0;i<N;i++){ printf("%c:",s[i]); printf("%s\n",hc[i]); } } void chartocode(charcode c,char s[],HuffmanCode hc){ //輸出編碼串 char *p=c; while(*p!='\0'){ for(int j=0;j<N;j++){ if(*p==s[j]) printf("%s",hc[j]); } p++; } printf("\n"); } void numtochar(numcode ns,HuffmanTree ht,char s[]){ //輸出譯碼串 char *p=ns; int key; HTNode g; while(*p!='\0'){ g=ht[M-1]; while(g.lchild!=-1&&g.rchild!=-1&&(*p!='\0')){ switch(*p){ case '0': key=g.lchild; g=ht[g.lchild]; break; case '1': key=g.rchild; g=ht[g.rchild]; break; } p++; } printf("%c",s[key]); } } int main(){ HuffmanTree ht; //哈夫曼樹 二叉樹 HuffmanCode hc; //字元編碼 字元指標陣列 charcode c; //編碼串 字元陣列 numcode ns; //譯碼串 字元陣列 char s[N]={'A','B','C','D','E','F'}; int w[N]; for(int i=0;i<N;i++) scanf("%d",&w[i]); //頻度陣列 scanf("%s",&c); //編譯碼 scanf("%s",&ns); //譯碼串 CrtHuffmanTree(ht,w); //建立哈夫曼樹 CrtHuffmanCode(ht,hc); printcode(s,hc); //列印各字元及編碼 chartocode(c,s,hc); //列印編碼串 numtochar(ns,ht,s); //列印譯碼串 }