• 哈夫曼树实现哈夫曼编码(C++)


       题目要求:根据哈夫曼编码的原理,编写一个程序,在用户输入结点权值的基础上求赫夫曼编码,并能把给定的编码进行译码。

    (1)初始化:从键盘输入一字符串(或读入一文件),统计出现的字符和每个字符出现的频率,将字符出现的频率作为结点的权值,建立哈夫曼树。对各个字符进行哈夫曼编码,最后打印输出字符及每个字符对应的哈夫曼编码。

    (2)编码:利用已建好的哈夫曼树对“输入串”进行哈夫曼编码,最后打印输入串对应的哈夫曼编码(写入文件)。

    (3)译码:利用已建好的哈夫曼树对给定的一串代码进行译码,并打印输出得到的字符串。(选作)

    1. #include
    2. #include
    3. #include
    4. #include
    5. using namespace std;
    6. map<char, int> mp;
    7. typedef struct node
    8. {
    9. int data=0;
    10. char name;
    11. }node;
    12. node sum[100];
    13. typedef struct Ht
    14. {
    15. int w;
    16. char name;
    17. string code;
    18. int parent, lchild, rchild;
    19. }Ht,*Htree;
    20. int flag[100] = { 0 };
    21. void Select(Htree& ht, int n, int& s1, int& s2)
    22. {
    23. int min1 = 999, min2 = 999;
    24. for (int i = 1; i <= n; i++)//查找权值第一小的点
    25. {
    26. if (flag[i] == 0 && (ht[i].w < min1))
    27. {
    28. min1 = ht[i].w;
    29. s1 = i;
    30. ht[i].code = "0";//小的在左
    31. }
    32. }
    33. flag[s1] = 1;//标记该点移出
    34. for (int i = 1; i <= n; i++)//查找权值第二小的点
    35. {
    36. if (flag[i] == 0 && (ht[i].w < min2))
    37. {
    38. min2 = ht[i].w;
    39. s2 = i;
    40. ht[i].code = "1";//大的在右
    41. }
    42. }
    43. flag[s2] = 1;//标记该点移出
    44. }
    45. void Inithtree(Htree& ht, int n)//初始化
    46. {
    47. if (n <= 1) return;
    48. int m = 2 * n - 1;
    49. ht = new Ht[m + 1];
    50. for (int i = 1; i <= m; i++)//将1到m点中的父亲、左孩子、右孩子下标都初始为0
    51. {
    52. ht[i].name = sum[i].name;
    53. ht[i].parent = 0, ht[i].lchild = 0, ht[i].rchild = 0;
    54. ht[i].w = sum[i].data;
    55. }
    56. }
    57. void Createtree(Htree& ht, int n)
    58. {
    59. int s1, s2;
    60. for (int i = n + 1; i <= 2 * n - 1; i++)//循环n-1次,建树
    61. {
    62. Select(ht, i - 1, s1, s2);//查找两个父亲为0且权值最小的点,并返回序号s1、s2
    63. ht[s1].parent = i, ht[s2].parent = i;//s1、s2父亲改为i
    64. ht[i].lchild = s1, ht[i].rchild = s2;//s1、s2分别作为i的左右孩子
    65. ht[i].w = ht[s1].w + ht[s2].w;//i的权值为左右孩子权值之和
    66. }
    67. }
    68. void Printtree(Htree& ht, int n)//打印
    69. {
    70. for (int i = 1; i <= 2 * n - 1; i++)
    71. cout << ht[i].name << " " << ht[i].w << " " << ht[i].parent << " " << ht[i].lchild << " " << ht[i].rchild << endl;
    72. }
    73. void bianma(Htree& ht, int n)//编码
    74. {
    75. for (int i = 1; i <= n; i++)
    76. {
    77. int parent = ht[i].parent;//获取该点父亲
    78. while (parent != 0)//不到根节点
    79. {
    80. ht[i].code = ht[parent].code + ht[i].code;//编码等于父亲加上自身
    81. parent = ht[parent].parent;//找父亲的父亲
    82. }
    83. }
    84. }
    85. int main()
    86. {
    87. Htree h;
    88. string str;
    89. cin >> str;
    90. for (int i = 0; i < str.length(); i++)
    91. {
    92. mp[str[i]]++;
    93. }
    94. int k = 1;
    95. int n = mp.size();//字符种类
    96. for (auto i : mp)
    97. {
    98. sum[k].name = i.first;
    99. sum[k++].data = i.second;
    100. }
    101. Inithtree(h, n);
    102. Createtree(h, n);
    103. //Printtree(h, n);
    104. bianma(h, n);
    105. cout << "编码:" << endl;
    106. for (int i = 1; i <= n; i++)//输出各字符的编码
    107. cout << h[i].name << ": " << h[i].code << endl;
    108. for (int i = 0; i < str.length(); i++)//字符串转为编码
    109. {
    110. for (int j = 1; j <= n; j++)
    111. {
    112. if (str[i] == h[j].name)
    113. {
    114. cout << h[j].code << " ";
    115. break;
    116. }
    117. }
    118. }
    119. cout << endl;
    120. string str1;
    121. string str2[100];
    122. int d = 0;
    123. cout << "译码:" << endl;
    124. cin >> str1;
    125. for (int i = 0; i < str1.length(); i++)
    126. {
    127. str2[d] += str1[i];
    128. for (int j = 1; j <= n; j++)
    129. {
    130. if (str2[d] == h[j].code)
    131. {
    132. cout << h[j].name;
    133. d++;
    134. break;
    135. }
    136. }
    137. }
    138. }

  • 相关阅读:
    java计算机毕业设计摄影网上预约管理系统源码+mysql数据库+系统+lw文档+部署
    Zlib和Zstd 性能对比评测
    C++学习笔记(二十)
    elasticsearch-dump 迁移es数据 (elasticdump)
    docker应用记录总结
    JS奇淫技巧:挑战前端黑科技,数值的七种写法,能全看懂的一定是高手
    PicGo+Gitee+Typora搭建云图床
    Java基础函数式编程
    能带你起飞的【数据结构】成王第十篇:二叉树4
    C语言逻辑与、或操作符、条件操作符、逗号表达式、下标引用、函数调用、结构体调用操作符
  • 原文地址:https://blog.csdn.net/qq_74156152/article/details/133896371