• (未学懂,待填坑)【数据结构】哈夫曼树


    知识点

    一 . 哈夫曼树的定义、构造及其遍历

    哈夫曼树也被称为最优二叉树,对于给定的一系列带权的叶子结点,带权路径长度WPL(Weighted Path Length)最短的二叉树。

    哈夫曼树中的叶节点的个数比非叶节点的个数多一。

    二 . 哈夫曼编码/霍夫曼编码 / Huffman编码

    哈夫曼编码是可变字长编码(ULC)的一种。

    1952年由Huffman提出的一种编码方法。完全依照字符出现的概率来构造编码,使其成为平均长度最短的编码方式,有时称为最佳编码。

    哈夫曼编码的码字(各符号的代码)是异前置码字,即任一码字不会是另一码字的前面部分,这使各码字可以连在一起传送,中间不需要另外加隔开的符号,只要传送的时候不出错,接收端仍可以分离各个码字,不致混淆。


    模板题

    例题:P2168 [NOI2015] 荷马史诗 

    思路:(待填坑)

    这道题实际上要求k叉Huffman树,及由两个分叉变为k个分叉(k叉树)。

    但真正去跑的时候你才发现,最后一次合并之后,堆中剩下m个值。但如果1堆中只剩一个值却不能合并

    所以我们使用补点这个方法,以达到堆中只剩一个值这个目的。

    首先,我们每次合并用掉 k 个值又合并出1个值,那么按每次合并来算,我们每次用掉了k-1个值。然后,我们最终需要只剩1个值,即需要合并n-1个值。那么我们只需要让(n-1)%(k-1)==0 成立不就可以了,但要使(n−1)%(k-1)==0成立,我们还需要补 (k-1)−((n−1)%(k-1)) 个点,但要使答案不受影响,我们就用权值为0的点来补。

    1. #include
    2. #include
    3. #include
    4. #include
    5. #include
    6. #define ll long long int
    7. using namespace std;
    8. int n,k;
    9. ll w,ans1=0,ans2=0;
    10. struct tree{
    11. ll w,h;
    12. };
    13. priority_queue q;
    14. bool operator < (tree a,tree b)
    15. {
    16. if(a.w!=b.w) return a.w > b.w;
    17. return a.h>b.h;
    18. }
    19. inline ll read()
    20. {
    21. ll x=0,f=1;
    22. char c=getchar();
    23. while(c<'0'||c>'9')
    24. {
    25. if(c=='-') f=-1;
    26. c=getchar();
    27. }
    28. while(c>='0'&&c<='9')
    29. {
    30. x=(x<<1)+(x<<3)+(c^48);
    31. c=getchar();
    32. }
    33. return x*f;
    34. }
    35. int main()
    36. {
    37. n=read(); k=read();
    38. for(int i=1;i<=n;++i)
    39. {
    40. w=read();
    41. q.push((tree){w,1});
    42. }
    43. ll cnt;
    44. if((n-1)%(k-1)!=0) //存在节点不在哈夫曼树中
    45. {
    46. cnt=(k-1)-((n-1)%(k-1)); //需要补点的数量
    47. for(int i=1;i<=cnt;++i)
    48. {
    49. q.push((tree){0,1}); //把这些节点的权值标为0
    50. }
    51. }
    52. ll len,value;
    53. while(q.size()>1)
    54. {
    55. ll sumw=0,Max=0;
    56. for(int i=1;i<=k;++i)
    57. {
    58. tree temp=q.top(); //在循环中取数
    59. len=temp.h; value=temp.w;
    60. sumw+=value;
    61. Max=max(Max,len);
    62. q.pop();
    63. }
    64. q.push((tree){sumw,Max+1});
    65. ans1+=sumw;
    66. ans2=max(ans2,Max); //(待填坑)为什么这里用max
    67. }
    68. printf("%lld\n%lld",ans1,ans2);
    69. return 0;
    70. }


    相关练习

     

  • 相关阅读:
    Java学习笔记(三):抽象类
    GoF之代理模式
    数位DP - 带49的数
    prokka-原核及病毒基因组高效便捷注释
    多重背包问题
    港澳通行证识别易语言代码
    Vue项目后台部分2,文件夹介绍,登录页面,路由的搭建,品牌管理页面使用element-ui动态展示
    二本菜鸡,颓废两年的自我救赎
    受了刺激,决定专升本
    hadoop四种集群模式
  • 原文地址:https://blog.csdn.net/gzkeylucky/article/details/126876504