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

原贴地址:http://blog.csdn.net/feixiaoxing/article/details/6960990

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


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

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

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

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

[cpp]  view plain copy
  1. /* 
  2. *   
  3. *           total_1(0.3)           C (0.3)   D(0.4) 
  4. *          /         \ 
  5. *        A(0.1)      B(0.2) 
  6. */  
    第二步,接着合并total_1和C,

[cpp]  view plain copy
  1. /* 
  2. *                 total_2 (0.6) 
  3. *               /          \      
  4. *           total_1(0.3)    C (0.3)    D(0.4) 
  5. *          /         \ 
  6. *        A(0.1)      B(0.2) 
  7. */  
    最后一步,合并total_2和D,

[cpp]  view plain copy
  1. /* 
  2. *            final (1.0) 
  3. *          /       \           
  4. *       D (0.4)    total_2 (0.6)     
  5. *                /          \      
  6. *           total_1(0.3)    C (0.3)    
  7. *          /         \ 
  8. *        A(0.1)      B(0.2) 
  9. */  
    所以按照上面的生成树,数据的编号应该这么安排,

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

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

[cpp]  view plain copy
  1. typedef struct _HUFFMAN_NODE  
  2. {  
  3.     char str;  
  4.     double frequence;  
  5.     int symbol;  
  6.     struct _HUFFMAN_NODE* left;  
  7.     struct _HUFFMAN_NODE* right;  
  8.     struct _HUFFMAN_NODE* parent;  
  9.   
  10. }HUFFMAN_NODE;  
    其中str记录字符,frequency记录字符出现的频率, symbol记录分配的数据,左子树为1、右子树为0,left为左子树,right为右子树,parent为父节点。接下来,我们从创建huffman结点开始。

[cpp]  view plain copy
  1. HUFFMAN_NODE* create_new_node(char str, double frq)  
  2. {  
  3.     HUFFMAN_NODE* pNode = (HUFFMAN_NODE*)malloc(sizeof(HUFFMAN_NODE));  
  4.     assert(NULL != pNode);  
  5.   
  6.     pNode->str = str;  
  7.     pNode->frequence = frq;  
  8.     pNode->symbol = -1;  
  9.     pNode->left = NULL;  
  10.     pNode->right = NULL;  
  11.     pNode->parent = NULL;  
  12.     return pNode;  
  13. }  


【未完,待续】
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值