当前位置:   article > 正文

【算法设计与分析】哈夫曼编码问题_哈夫曼编码假设需要编码的字符集为{d1, d2, …, dn},它们出现的频率为 {w1, w2,

哈夫曼编码假设需要编码的字符集为{d1, d2, …, dn},它们出现的频率为 {w1, w2,

一、实验题目:

     设需要编码的字符集为{d1, d2, …, dn},它们出现的频率为{w1, w2, …, wn},应用哈夫曼树构造最短的不等长编码方案。

二、实验要求:

1)证明哈夫曼树满足最优子结构性质;

2)设计贪心算法求解哈夫曼编码方案;

3)设计测试数据,写出程序文档。

三、实验代码:

  1. #include <iostream>
  2. using namespace std;
  3. #define MAXCODELEN 100 //最大字符编码数组长度
  4. #define MAXHAFF 100 //最大哈夫曼节点结构体数组个数
  5. #define MAXCODE 100 //最大哈夫曼编码结构体数组的个数
  6. #define MAXWEIGHT 10000; //最大字符编码权值
  7. typedef struct Huffman{
  8. int weight; //权重
  9. char ch; //字符
  10. int parent; //父节点
  11. int leftChild; //左儿子节点
  12. int rightChild; //右儿子节点
  13. }HuffmanNode;
  14. typedef struct Code{
  15. int code[MAXCODELEN]; //字符的哈夫曼编码的存储
  16. int start; //从哪个位置开始
  17. }HuffmanCode;
  18. HuffmanNode huffman[MAXHAFF];
  19. HuffmanCode code[MAXCODE];
  20. void createHuffman(int all){
  21. //初始化Huffman树
  22. for (int i = 0; i < all * 2 - 1; ++i){
  23. huffman[i].weight = 0;
  24. huffman[i].parent = -1;
  25. huffman[i].leftChild = -1;
  26. huffman[i].rightChild = -1;
  27. }
  28. /*提示用户输入数据*/
  29. cout << "请依次输入" << all << "个需要哈夫曼编码的字符:";
  30. for (int i = 0; i < all;i++) {
  31. cin >> huffman[i].ch;
  32. }
  33. cout << "请依次输入"<<all<<"个字符对应的的权值:";
  34. for (int i = 0; i < all; i++) {
  35. cin >> huffman[i].weight;
  36. }
  37. //每次循环找出权值最小的两个节点,生成新的父亲节点。共需要 all - 1 次合并
  38. int x1, x2, w1, w2; //w1、w2分别为最小的两个节点
  39. for (int i = 0; i < all - 1; ++i){
  40. x1 = x2 = -1;
  41. w1 = w2 = MAXWEIGHT; //初始化最小节点权值
  42. for (int j = 0; j < all + i; ++j){
  43. if (huffman[j].parent == -1 && huffman[j].weight < w1){ //找到无父节点并且权值最小
  44. w2 = w1;
  45. x2 = x1;
  46. x1 = j;
  47. w1 = huffman[j].weight;
  48. }
  49. else if (huffman[j].parent == -1 && huffman[j].weight < w2){ //找到第二小的无父亲节点
  50. x2 = j;
  51. w2 = huffman[j].weight;
  52. }
  53. }
  54. //将上面找到的最小权值节点合并成一个新的父亲节点
  55. huffman[all + i].leftChild = x1;
  56. huffman[all + i].rightChild = x2;
  57. huffman[all + i].weight = w1 + w2;
  58. huffman[x1].parent = all + i;
  59. huffman[x2].parent = all + i;
  60. }
  61. }
  62. //打印每个字符的哈夫曼编码
  63. void printCode(int all){
  64. HuffmanCode hCode;//保存当前叶子节点的字符编码
  65. int curParent; //当前父节点
  66. int c; //下标和叶子节点的编号
  67. for (int i = 0; i < all; ++i) {
  68. hCode.start = all - 1;
  69. c = i;
  70. curParent = huffman[i].parent;
  71. while (curParent != -1) {
  72. if (huffman[curParent].leftChild == c){ hCode.code[hCode.start] = 0; }
  73. else{ hCode.code[hCode.start] = 1; }
  74. hCode.start--;
  75. c = curParent;
  76. curParent = huffman[c].parent;
  77. }
  78. //把当前的叶子节点信息保存到编码结构体里面
  79. for (int j = hCode.start + 1; j < all; ++j){
  80. code[i].code[j] = hCode.code[j];
  81. }
  82. code[i].start = hCode.start;
  83. }
  84. cout << endl;
  85. for (int i = 0; i < all; ++i) {
  86. cout << huffman[i].ch << " 字符的哈夫曼编码是:";
  87. for (int j = code[i].start + 1; j < all; ++j) {
  88. cout << code[i].code[j];
  89. }
  90. cout << endl;
  91. }
  92. }
  93. int main(){
  94. int all = 0;
  95. cout << "请输入哈夫曼字符个数:"; cin >> all;
  96. if (all <= 0){
  97. cout << "您输入的个数有误" << endl;
  98. return -1;
  99. }
  100. createHuffman(all);
  101. printCode(all);
  102. return 0;
  103. }

四、实验结果:

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/神奇cpp/article/detail/891037
推荐阅读
相关标签
  

闽ICP备14008679号