哈弗曼树
来源:互联网 发布:交通事故数据统计 编辑:程序博客网 时间:2024/06/07 14:17
哈弗曼树原理暂时不叙述(实为贪心算法)。先奉上自己写的源代码。
/* huffman tree */#include<stdio.h>#include<string.h>#include<stdlib.h>#define N 100typedef struct _arrTree{int weight;int parent;int lchild;int rchild;}arrayTree,*pArrayTree;typedef struct _tree{int data;int visit;char code[256];struct _tree *left;struct _tree * right;}tree,*pTree;void initArray(pArrayTree at,int* len){int i=0;scanf("%d",len);while(scanf("%d",&((at+i)->weight)),++i<*len);}void arrayCreate(pArrayTree at,int len){int min1,min2,j,k=len;if(len<2){printf("the tree is so small!\n");return;}for(;k<2*len-1;++k){min1=0;while(at[min1].parent){++min1;}min2=min1+1;while(at[min2].parent){++min2;}for(j=0;j<k;++j){if(at[j].parent||j==min1||j==min2){continue;}if(at[min1].weight>at[min2].weight){int t=min1;min1=min2;min2=t;}if(at[j].weight<at[min1].weight){min2=min1;min1=j;}else if(at[j].weight<at[min2].weight){min2=j;}}at[k].weight=at[min1].weight+at[min2].weight;at[k].lchild=min1;at[k].rchild=min2;at[min1].parent=k;at[min2].parent=k;}}void show(pArrayTree at,int len){int i=0;printf("index weight parent lchild rchild\n");for(;i<2*len-1;++i){printf("%-7d%-7d%-7d%-7d%-7d\n",i,at[i].weight,at[i].parent,at[i].lchild,at[i].rchild);if(i==len-1){printf("---------------------------------------\n");}}}pTree createTree(pTree root,pArrayTree at,int len){int i=2*len-2;root=(pTree)malloc(sizeof(tree)*(2*len-1));while(i>=0){root[i].data=at[i].weight;if(at[i].lchild){root[i].left=root+at[i].lchild;root[i].right=root+at[i].rchild;}else{root[i].left=NULL;root[i].right=NULL;}--i;}return root+2*len-2;}void traverse(pTree root,char* str){ //遍历并建立码表。if(root){ char st[256]="";printf("%-5d ",root->data);strcpy(root->code,str);printf("%s\n",root->code);strcpy(st,root->code);traverse(root->left,strcat(st,"0"));//关键st[strlen(st)-1]='1';st[strlen(st)]=0;traverse(root->right,st);//关键}}/* show the code */void showCode(pTree root){if(root){if(!root->left&&!root->right){printf("%-5d %s\n",root->data,root->code);}showCode(root->left);showCode(root->right);}}void initCodes(char (*codes)[256],int len,pTree root){int i=0;for(;i<len;++i){strcpy(codes[i],(root-2*len+2+i)->code);}}void showInitCode(char (*codes)[256],int len){int i=0;for(;i<len;++i){printf(" %s\n",codes[i]);}}void decode(char (*codes)[256],int len,const char* str){char* ps=str;char res[1024]="";int num[N]={0},i;for(i=0;i<len;++i){num[i]=strlen(codes[i]+1);}while(*ps){ //暂时是暴力解码,待日后想出一个更优秀的算法for(i=0;i<len;++i){char ss[256]="";strncpy(ss,ps,num[i]);if(!strcmp(ss,codes[i]+1)){printf("%d",i);//此处用于调试输出。// strcat(res,itoa(i,ss,10));sprintf(ss,"%d",i);strcat(res,ss);ps+=num[i];break;}}}printf("\n%s\n",res);}int main(){int len;char codes[N][256];char source[1024];pTree root;arrayTree at[2*N-1]={{0,0,0,0}};initArray(at,&len);arrayCreate(at,len);show(at,len);printf("\n");root=createTree(root,at,len);traverse(root,"#");printf("\n");showCode(root);initCodes(codes,len,root);showInitCode(codes,len);getchar();gets(source);decode(codes,len,source);//执行解码操作return 0;}
测试数据
8
5 29 7 8 14 23 3 11
00000001001011011011101111
结果输出
100 #
42 #0
19 #00
8 #000
3 #0000
5 #0001
11 #001
23 #01
58 #1
29 #10
29 #11
14 #110
15 #111
7 #1110
8 #1111
3 #0000
5 #0001
11 #001
23 #01
29 #10
14 #110
7 #1110
8 #1111
#0001
#10
#1110
#1111
#110
#01
#0000
#001
65611757557557555755555
65611757557557555755555
0 0
- 哈弗曼树
- 哈弗曼树
- 哈弗曼树
- 哈弗曼树
- 哈弗曼树
- 哈弗曼树
- 哈弗曼树
- 哈弗曼树
- 哈弗曼树
- 哈弗曼树
- 哈弗曼树
- 哈弗曼树与哈弗曼树编码
- 哈弗曼树实现
- 数据结构--哈弗曼树
- 构造哈弗曼树
- 数据结构哈弗曼树
- 什么是哈弗曼树
- 创建哈弗曼树
- CSS中定义a:hover , a:visited , a:actived
- jasperreport开发实例及问题
- Cocos2d-x cocostudio UIButton控件setEnabled(false)方法失效解决办法
- oc
- linux中fork()函数详解(原创!!实例讲解)
- 哈弗曼树
- check_postgres脚本集
- 一种快速加载大文件的方法
- duilib作为播放器的ui嵌入到mfc中使用
- 多线程编程4-------面试题增加信号
- 大概就是这个意思吧~
- php & 和 & (主要是url 问题)
- 离散数学及其应用——ch6 离散概率论
- mysql数据库如何修复