哈夫曼树构造及哈夫曼编码
前情提要
请为用于通信的电文中的字母进行赫夫曼编码。如各个字母在电文中出现的频率分别为0.05,0.29,0.07,0.08,0.14,0.23,0.03,0.11。试为这8个字母设计哈夫曼编码。
通信的电文中的字母一般是a,b,c,d,e,f,g,h
根据其出现的概率可设8个字符的权值为:w=(5,29,7,8,14,23,3,11)
将树的左分支标记为0,右分支标记为1,便得到其哈夫曼编码表
代码函数
void CreateHT(HTNode ht[],int n);//构造哈夫曼树
void CreateHCode(HTNode ht[],HCode hcd[],int n);//构造哈夫曼编码
void DispHCode(HTNode ht[],HCode hcd[],int n);//输出哈夫曼编码
代码实现
#include<stdio.h>
#include<string.h>
#define N 50 //叶子节点数
#define M 2*N-1 //树中节点总数
typedef struct
{char data[5]; //节点值int weight; //权重int parent; //双亲节点int lchild; //左孩子节点int rchild; //右孩子节点
}HTNode;
typedef struct
{char cd[N];//存放哈夫曼码int start;
}HCode;void CreateHT(HTNode ht[],int n);//构造哈夫曼树
void CreateHCode(HTNode ht[],HCode hcd[],int n);//构造哈夫曼编码
void DispHCode(HTNode ht[],HCode hcd[],int n);//输出哈夫曼编码void CreateHT(HTNode ht[],int n)//构造哈夫曼树
{int i,k,lnode,rnode;int min1,min2;//设置权重最小的两个节点for(i=0;i<2*n-1;i++)//所有节点的相关域设置初始值为-1{ht[i].parent=ht[i].lchild=ht[i].rchild=-1;}for(i=n;i<2*n-1;i++)//构造哈夫曼树{ //n前面的空间给输入的值,树的其他节点给算出来的权重和min1=min2=32767;//min1为第一个最小的权重,min2为第二个最小的权重lnode=rnode=-1;//lnode和rnode为最小权重的两个节点位置for(k=0;k<=i-1;k++)if(ht[k].parent==-1)//只在尚未构造二叉树的节点中查找{if(ht[k].weight<min1)//找权重最小的两个节点{min2=min1;rnode=lnode;//把min1的下标值给了min2,原左孩子的下标lnode给右孩子的下标rnodemin1=ht[k].weight;lnode=k;//把权重最小的下标赋给lnode}else if(ht[k].weight<min2){min2=ht[k].weight;rnode=k;//把权重第二最小的下标赋给rnode}}ht[lnode].parent=i;ht[rnode].parent=i;//将当前权重最小的两个的双亲节点设为下标为i的节点ht[i].weight=ht[lnode].weight+ht[rnode].weight;//下标为i的节点的权重为两个子女的权重和ht[i].lchild=lnode;ht[i].rchild=rnode;//设置下标为i的节点的孩子为下标为lnode和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;//c获取当前节点的下标f=ht[i].parent;//获取输入的叶子节点的双亲节点下标while(f!=-1)//循序直到树根节点,树根节点的双亲节点下标为-1{if(ht[f].lchild==c)//处理左孩子节点,判断当前双亲节点的左孩子是否是节点为c下标,是,就处理hc.cd[hc.start--]='0';//hc.start--从当前节点开始标记0/1一直到根节点else //处理右孩子,判断当前双亲节点的右孩子是否是节点为c下标,是,就处理hc.cd[hc.start--]='1';c=f;f=ht[f].parent;//c获取当前节点的下标,f获得双亲节点下标}hc.start++;//start指向哈夫曼编码最开始字符,最后一次循环产生作用hcd[i]=hc;}
}void DispHCode(HTNode ht[],HCode hcd[],int n)//输出哈夫曼编码
{int i,k;printf("输出哈夫曼编码:\n");for(i=0;i<n;i++){printf(" %s:\t",ht[i].data);for(k=hcd[i].start;k<=n;k++){printf("%c",hcd[i].cd[k]);}printf("\n");}
}void main()
{int n=8,i;HTNode ht[M];HCode hcd[N];char *str[]={"a","b","c","d","e","f","g","h"};int fnum[]={5,9,7,8,14,23,3,11};for(i=0;i<n;i++){strcpy(ht[i].data,str[i]);ht[i].weight=fnum[i];}CreateHT(ht,n);CreateHCode(ht,hcd,n);DispHCode(ht,hcd,n);
}
输出
哈夫曼树构造及哈夫曼编码相关推荐
- 哈夫曼树构造以及代码实现
哈夫曼树构造以及代码实现 什么是哈夫曼树 理解哈夫曼树 哈夫曼树的构造 哈夫曼树构造-代码实现 什么是哈夫曼树 构造一颗二叉树,该树的带权路径长度达到最小,称为最优二叉树,也称为哈夫曼树(Huffma ...
- 哈夫曼树构造哈夫曼编码
在传输文字时,经常要将文字转换成二进制字符串.所以我们希望编码最短,但是又想保证它的唯一性.哈夫曼树具有最小带权路径长度,用来实现编码就可以编码最短,所以用哈夫曼树来构造编码.而前缀编码就可以保证在解 ...
- 算法学习笔记10——应用哈夫曼树构造最短的不等长编码方案
内容: (1)设需要编码的字符集为{d1, d2, -, dn},它们出现的频率为{w1, w2, -, wn},应用哈夫曼树构造最短的不等长编码方案. 提示: 哈夫曼树(Huffman Tree), ...
- 哈夫曼树构造算法的正确性证明
哈夫曼树构造 1.哈夫曼树的定义 给定n个权值作为n个叶子结点,构造一棵二叉树,若带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman tree). 2.哈夫曼树的构造 假 ...
- 【Lua】哈夫曼树构造算法的分析与实现
哈夫曼树构造算法分析 1.哈夫曼树中权重越大的叶子离根越近,采用贪心算法构造哈夫曼树,首先选中权重值小的叶子结点进行构造 2.步骤 构造森林全是根:根据n个给定结点的权重值{W1, W2-Wn}构成 ...
- c语言哈夫曼树构造代码
c语言哈夫曼树构造代码 博主就很掘的一个人,最近学哈夫曼树,想着用指针去实现,觉得用指针实现,内存消耗会更少,写到后面发现越来与麻烦,且内存开销并没有减少,于是还是使用结构体数组中规中矩的去实现哈夫曼 ...
- 最小堆实现哈夫曼树构造
0. 序 本以为用最小堆实现个哈夫曼树是个简单的事情,结果一不小心就花了好几个小时才写完...实现过程中主要有三个方面的问题没注意,导致花了很多时间进行调试. 一是多重指针malloc分配时要多加注意 ...
- 数据结构编程实践(七)创建哈夫曼树、生成哈夫曼编码、完成图片的压缩与解压缩
一.对图片的压缩与解压缩,涉及以下内容: 1.文件读写 2.创建Huffman树 3.生成Huffman编码 4.压缩图片文件 5 . 解压缩图片文件 二.将项目分成三个小任务,下一任务是在上一任务 ...
- 哈夫曼树+K叉哈夫曼树
目录 基本概念 构造方法 证明 代码 k叉哈夫曼树 例题 基本概念 问题:给定n个权值,作为n个叶结点,构造一棵二叉树,而这棵树的特点是,有n个叶节点,叶节点的值为给定的权值.而内部节点的值为子树的权 ...
- 【哈夫曼树】创建哈夫曼树
文章目录 基础概念: 什么是路径? 什么是路径长度? 什么是[结点]的带权路径长度? 什么是[树]的带权路径长度? 如何构建一棵哈夫曼树? 1.构建森林: 设计哈夫曼树 优先级队列:(priority ...
最新文章
- python批量提取word指定内容_使用python批量读取word文档并整理关键信息到excel表格的实例...
- 参考: 40个轻量级 JavaScript 库
- Linux Kernel中gicv3实现:SPIs中断routing到指定的CPU
- 单片机实用工具大全,超级赞,工程师必备!
- android串口工具apk_【APK】一个强大的Android开发工具!
- MFC将bmp图像设为背景
- 计算机网络八校联考试题,2019届高三信息技术3月联考试卷有解析与答案
- php编写程序计算积分_PHP论坛实现积分系统的思路代码详解
- 如何删除ppt自带背景音乐_ppt模板里自带的背景乐怎么去掉?
- mysql.sock介绍
- Ethernet和802.3的区别及历史
- [转]使用ArcGIS实现WGS84经纬度坐标到北京54高斯投影坐标的转换
- 面试题之10亿正整数问题
- 用c语言用*组成C字母,C语言字符集由字母,数字,空格,标点符号和特殊字符组成...
- 克鲁斯卡尔(Kruskal)算法(严蔚敏C语言)
- Vin码识别功能实现
- CAD二次开发学习笔记四(得到选中的实体,修改实体,如等分线段)
- 程序员面试揭秘之程序员靠什么途径去美国工作
- 电脑快捷修改计算机名
- 谈谈数据挖掘和机器学习