如何建立一棵哈夫曼树并且输出压缩码
来源:互联网 发布:数据库关联 编辑:程序博客网 时间:2024/04/29 22:46
如何建立一棵哈夫曼树并且输出压缩码
算法:1、给定一个具有n个权值{ w1,w2,………wn }的结点的集合 F = { T1,T2,………Tn } 2、初始时,设集合 A = F。 3、执行 i = 1至 n -1的循环,在每次循环时执行以下操作从当前集合中选取权值最小、次最小的两个结点,以这两个结点作为内部结点 bi的左右儿子,bi的权值为其左右儿子权值之和。在集合中去除这两个权值最小、次最小的结点,并将内部结点bI加入其中。这样,在集合A中,结点个数便减少了一个。这样,在经过了n-1次循环之后,集合A中只剩下了一个结点,这个结点就是根结点。
哈夫曼树的存储:在哈夫曼树中,每个要编码的元素是一个叶结点(度数为零),其它结点都是度数(度数就是有多少个子节点)为2的节点一旦给定了要编码的元素个数,由n0=n2+1可知哈夫曼树的大小为2n-1哈夫曼树可以用一个大小为2n的数组来存储。0节点不用,根存放在节点1。叶结点依次放在n+1到2n的位置每个数组元素保存的信息:结点的数据、权值和父结点和左右孩子的位置。
代码实现:
//哈夫曼树及其编码,两个结构体,第一个是用来构造哈夫曼树的,第二个是用来保存压缩码的
#include<iostream>using namespace std;struct hfnode{ char data;//字符 int weight;//字符的个数,也就是权值 int parent,left,right;//父节点、左子树、右子树的数组下标};struct node{ char data;//字符 char a[1000];//用于保存压缩码 int num;//压缩码的长度};struct node *hftree(char str[],int d[],int size){ int lenth=size*2,min1,min2,x,y,i,j; struct hfnode *hf; struct node *p; hf=(struct hfnode *)malloc(lenth*sizeof(struct hfnode)); p=(struct node *)malloc(size*sizeof(struct node)); for(i=size; i<lenth; i++) //size到(lenth-1)用来存放叶子节点 { hf[i].data=str[i-size]; hf[i].weight=d[i-size]; hf[i].parent=hf[i].left=hf[i].right=0; } for(i=size-1; i>0; i--) //哈夫曼树的构造 { min1=min2=100000000; x=y=0;//min1用来保存最小的,min2用来保存次小的 for(j=i+1; j<lenth; j++) { if(min1>hf[j].weight&&hf[j].parent==0) { min2=min1; y=x; min1=hf[j].weight; x=j; } else if(min2>hf[j].weight&&hf[j].parent==0) { min2=hf[j].weight; y=j; } } if(x>y) swap(x,y); hf[i].weight=min1+min2;//新的节点的形成 hf[i].parent=0; hf[i].left=x; hf[i].right=y; hf[x].parent=i; hf[y].parent=i; } for(i=size; i<lenth; i++) //求出各个字符的压缩码 { int t1,t2; p[i-size].data=hf[i].data; p[i-size].num=0; t1=hf[i].parent;//父节点的数组下标 t2=i;//自身的数组下标 while(t1>0) { if(hf[t1].left==t2) p[i-size].a[p[i-size].num++]='0'; else p[i-size].a[p[i-size].num++]='1'; t2=t1; t1=hf[t1].parent; } } return p;}int main(){ char str[1000]; int b[26],c[26],i,j,n,size; struct node *temp; while(scanf("%d",&n)!=EOF)//测试案例的个数 { getchar(); while(n--) { size=0; memset(b,0,sizeof(b)); scanf("%s",str); for(i=0; str[i]!='\0'; i++) b[str[i]-'a']++; for(i=0; i<26; i++) if(b[i]!=0) { c[size]=b[i]; str[size]=i+'a'; size++; }//c数组中保存的是各个字符的权值(也就是个数) temp=hftree(str,c,size); for(i=0; i<size; i++) { printf("%c:",temp[i].data); for(j=temp[i].num-1; j>=0; j--) printf("%c",temp[i].a[j]); printf("\n"); } } } return 0;}
0 0
- 如何建立一棵哈夫曼树并且输出压缩码
- 如何动态建立一个DataTable并且为之添加数据
- 如何建立release并且回滚不发布上线的功能
- Java中如何计算程序的运行时间并且输出
- 如何建立和输出一个简单链表
- 没有安装oracle客户端如何在本地建立表空间,并且创建用户
- 如何在Ubuntu14中编译ffmpeg,并且建立一个eclipse工程
- JAVA问题总结之30--输出当前精度为毫秒的时间并且按时间批量建立文件
- 如何把一个逗号分隔的字符串转换成数组 并且倒序输出
- Swing 中如何获取JTestField中的内容 并且 点击按钮输出
- 如何在控制器获取数据库的数据并且在模板输出
- Android图片压缩:按等比例压缩并且质量压缩
- 从键盘输入字符并且输出
- 矩阵斜着输出并且从下到上
- 在SQL Server 2000中,如何对数据库进行备份,并且压缩备份,拷贝到其他位置
- 首页> H5教程> 正文 关于html5中如何调用相机拍照并且压缩图片的示例详解
- ruby进行rpc服务的建立,并且设置端口号(XMLRPC 及 ruby的xmlrpc如何使用)
- 输出扩展ASCII码-如何输出小白块
- JAVA基础:多线程
- 《生死疲劳》
- 求3个数字的平均值而且保留到小数点后3位
- 【UML】概述以及面向对象技术总结
- 编辑文章 - 博客频道 - CSDN.NET
- 如何建立一棵哈夫曼树并且输出压缩码
- LeetCode | Evaluate Reverse Polish Notation
- Android之开发性能优化简介
- hdu 5002 Tree
- Spring3 mvc hello world demo
- UML关系(泛化,实现,依赖,关联(聚合,组合))
- [Android笔记]HandelThread使用
- Android App 内存泄露之Handler
- ZOJ 3209 Treasure Map (Dancing Links 精确覆盖 )