一步一步写算法(之哈夫曼树 上)

简介: 原文: 一步一步写算法(之哈夫曼树 上) 【 声明:版权所有,欢迎转载,请勿用于商业用途。  联系信箱:feixiaoxing @163.com】       在数据传输的过程当中,我们总是希望用尽可能少的带宽传输更多的数据,哈夫曼就是其中的一种较少带宽传输的方法。
原文: 一步一步写算法(之哈夫曼树 上)

【 声明:版权所有,欢迎转载,请勿用于商业用途。  联系信箱:feixiaoxing @163.com】 


     在数据传输的过程当中,我们总是希望用尽可能少的带宽传输更多的数据,哈夫曼就是其中的一种较少带宽传输的方法。哈夫曼的基本思想不复杂,那就是对于出现频率高的数据用短字节表示,对于频率比较低得数据用长字节表示。

    比如说,现在有4个数据需要传输,分别为A、B、C、D,所以一般来说,如果此时没有考虑四个数据出现的概率,那么我们完全可以这么分配,平均长度为2,

/*
*  A - 00         B - 01
*  C - 10         D - 11
*/
    但是,现在条件发生了改变,四个数据出现的频率并不一样,分别为0.1/0.2/0.3/0.4。那么这时候应该怎么分配长度呢,其实也简单。我们只要把所有数据按照频率从低到高排列,每次取前两位合并成新的节点,再把这个新节点放到队列中重新排序即可。新节点的左结点默认设为1,右结点默认设为0。然后重复上面的过程,直到所有的节点都合并成一个节点为止。如果应用到实际的示例中,合并的过程应该是这样的,

    第一步,首先合并A和B,因为A和B是概率最小的

/*
*  
*           total_1(0.3)           C (0.3)   D(0.4)
*          /         \
*        A(0.1)      B(0.2)
*/
    第二步,接着合并total_1和C,

/*
*                 total_2 (0.6)
*               /          \     
*           total_1(0.3)    C (0.3)    D(0.4)
*          /         \
*        A(0.1)      B(0.2)
*/
    最后一步,合并total_2和D,

/*
*            final (1.0)
*          /       \          
*       D (0.4)    total_2 (0.6)    
*                /          \     
*           total_1(0.3)    C (0.3)   
*          /         \
*        A(0.1)      B(0.2)
*/
    所以按照上面的生成树,数据的编号应该这么安排,

/*
*   A - 011       B - 010
*   C - 00        D - 1
*/
    看上去A和B的长度还增加了,但是D的长度减少了。那么整个数据的平均长度有没有减少呢?我们可以计算一下。3 * 0.1 + 3 * 0.2 + 2 * 0.3 + 0.4 = 1.9 < 2。我们发现调整后的数据平均长度比原来减少了近(2 - 1.9)/2 * 100% = 10 %,这可是巨大的发现啊。

    为了完成整个哈夫曼树的创建,我们还需要定义一个数据结构:

typedef struct _HUFFMAN_NODE
{
	char str;
	double frequence;
	int symbol;
	struct _HUFFMAN_NODE* left;
	struct _HUFFMAN_NODE* right;
	struct _HUFFMAN_NODE* parent;

}HUFFMAN_NODE;
    其中str记录字符,frequency记录字符出现的频率, symbol记录分配的数据,左子树为1、右子树为0,left为左子树,right为右子树,parent为父节点。接下来,我们从创建huffman结点开始。

HUFFMAN_NODE* create_new_node(char str, double frq)
{
	HUFFMAN_NODE* pNode = (HUFFMAN_NODE*)malloc(sizeof(HUFFMAN_NODE));
	assert(NULL != pNode);

	pNode->str = str;
	pNode->frequence = frq;
	pNode->symbol = -1;
	pNode->left = NULL;
	pNode->right = NULL;
	pNode->parent = NULL;
	return pNode;
}


【未完,待续】



目录
相关文章
|
24天前
|
存储 人工智能 算法
哈夫曼算法详细讲解(算法+源码)
哈夫曼算法详细讲解(算法+源码)
|
9月前
|
算法
修理牧场( 哈夫曼算法 ,贪心 )
修理牧场( 哈夫曼算法 ,贪心 )
125 0
|
11月前
|
存储 算法 Windows
用二叉树实现哈夫曼算法、哈夫曼树提升压缩比率及可逆压缩和非可逆压缩
用二叉树实现哈夫曼算法、哈夫曼树提升压缩比率及可逆压缩和非可逆压缩
49 0
|
11月前
|
存储 算法
RLE算法机制、缺点及哈夫曼算法和莫尔斯编码
RLE算法机制、缺点及哈夫曼算法和莫尔斯编码
102 0
|
存储 算法
【数据结构和算法】哈夫曼树及其应用
【数据结构和算法】哈夫曼树及其应用
315 0
【数据结构和算法】哈夫曼树及其应用
|
算法 Java 关系型数据库
算法之树(二,B+树、哈夫曼树、堆、红黑树)(Java版)-持续更新补充
B+树的优势 1.单一节点存储更多元素。B+树中间节点没有卫星数据(也就是说只包含索引信息),所以每个非叶子节点可以包含更多的内容,同样大小的磁盘页可以容纳更多的节点元素。也就是说B+树会在相同数据量的情况下比B树更加“矮胖”,查询的IO次数更少。
6029 0
|
算法 C++ 容器
STL实现哈夫曼算法
用C++ std::priority_queue 实现哈夫曼算法我想每个计算机专业的学生或多或少都接触过哈夫曼编码,数据结构中的老问题了。大体就是给出一些字符,和这些字符的出现频率,让你为这些字符设计一个二进制编码,要求频率最高的字符的编码最短。
1437 0
|
算法 测试技术 搜索推荐
一步一步写算法(之哈夫曼树 下)
原文: 一步一步写算法(之哈夫曼树 下) 【 声明:版权所有,欢迎转载,请勿用于商业用途。  联系信箱:feixiaoxing @163.com】     前面说到了哈夫曼树的创建,那下面一个重要的环节就是哈夫曼树的排序问题。
911 0
|
1月前
|
传感器 算法 计算机视觉
基于肤色模型和中值滤波的手部检测算法FPGA实现,包括tb测试文件和MATLAB辅助验证
该内容是关于一个基于肤色模型和中值滤波的手部检测算法的描述,包括算法的运行效果图和所使用的软件版本(matlab2022a, vivado2019.2)。算法分为肤色分割和中值滤波两步,其中肤色模型在YCbCr色彩空间定义,中值滤波用于去除噪声。提供了一段核心程序代码,用于处理图像数据并在FPGA上实现。最终,检测结果输出到&quot;hand.txt&quot;文件。
|
1月前
|
机器学习/深度学习 算法 计算机视觉
基于yolov2深度学习网络的视频手部检测算法matlab仿真
基于yolov2深度学习网络的视频手部检测算法matlab仿真