• C++ 数据结构 哈弗曼树的制作


     
    输入
    abbccc$
    输出
    9
    样例输入 Copy
    hello world$
    样例输出 Copy
    32
     
     

    1. #include
    2. #include
    3. #include
    4. #define MAX_SIZE 1000
    5. typedef char elemtype;
    6. //带权值的二叉树
    7. typedef struct BiTNode {
    8. elemtype data;
    9. int weight; //权重
    10. struct BiTNode* lchild, * rchild; /*左右孩子指针*/
    11. }BiTNode, * BiTree;
    12. //用单链表表示森林
    13. typedef struct linkNode {
    14. BiTree tree;
    15. struct linkNode* next;
    16. }LinkNode, * Forest;
    17. //创建森林
    18. int createForest(Forest& forest)
    19. {
    20. //待补全,读入字符串,以‘$'为结束符,根据每个字符出现频率为权值,构造森林。并返回森林中树的个数
    21. int count = 0; // 森林中树的个数
    22. BiTree tree;
    23. LinkNode* p = forest;
    24. char ch;
    25. char list[128] = {0};
    26. scanf("%c", &ch);
    27. while (ch != '$') {
    28. list[ch] += 1;
    29. scanf("%c", &ch);
    30. }
    31. for (int i = 0; i < 128; i++) {
    32. if (!list[i])
    33. continue;
    34. tree = (BiTNode*)malloc(sizeof(BiTNode));
    35. tree->data = i;
    36. tree->weight = list[i];
    37. tree->lchild = NULL;
    38. tree->rchild = NULL;
    39. LinkNode* newNode = (LinkNode*)malloc(sizeof(LinkNode));
    40. newNode->tree = tree;
    41. newNode->next = NULL;
    42. p->next = newNode;
    43. p = p->next;
    44. count++;
    45. }
    46. return count;
    47. }
    48. void sortForest(Forest forest)
    49. {
    50. int count = 0;
    51. LinkNode* p = forest->next;
    52. BiTree* trees = (BiTree*)malloc(sizeof(BiTree) * MAX_SIZE);
    53. // 将森林中所有的树存储到数组中
    54. while (p != NULL) {
    55. trees[count++] = p->tree;
    56. p = p->next;
    57. }
    58. // 使用冒泡排序将树按照权值从小到大排序
    59. for (int i = 0; i < count - 1; i++) {
    60. for (int j = 0; j < count - i - 1; j++) {
    61. if (trees[j]->weight > trees[j + 1]->weight) {
    62. BiTree tmp = trees[j];
    63. trees[j] = trees[j + 1];
    64. trees[j + 1] = tmp;
    65. }
    66. }
    67. }
    68. // 将排好序的树重新插入森林中
    69. p = forest->next;
    70. for (int i = 0; i < count; i++) {
    71. p->tree = trees[i];
    72. p = p->next;
    73. }
    74. free(trees);
    75. }
    76. BiTree createHuffmanTree(Forest forest)
    77. {
    78. // 将森林中的所有树按照权值从小到大排序
    79. sortForest(forest);
    80. // 合并森林中的树,直到只剩下一棵树为止
    81. while (forest->next->next != NULL) {
    82. BiTree t1 = forest->next->tree;
    83. BiTree t2 = forest->next->next->tree;
    84. // 创建新的二叉树节点,作为t1和t2的父节点
    85. BiTree newNode = (BiTree)malloc(sizeof(BiTNode));
    86. newNode->data = '#';
    87. newNode->weight = t1->weight + t2->weight;
    88. newNode->lchild = t1;
    89. newNode->rchild = t2;
    90. // 将新节点插入森林中,并删除t1和t2
    91. LinkNode* newLinkNode = (LinkNode*)malloc(sizeof(LinkNode));
    92. newLinkNode->tree = newNode;
    93. newLinkNode->next = forest->next->next->next;
    94. forest->next->next->next = newLinkNode;
    95. forest->next = forest->next->next->next;
    96. // 重新排序森林
    97. sortForest(forest);
    98. }
    99. // 返回剩下的最后一棵树,即哈夫曼树
    100. return forest->next->tree;
    101. }
    102. void calculateEncodingLength(BiTNode* root, int depth, int& totalLength) {
    103. if (!root) {
    104. return;
    105. }
    106. if (!root->lchild && !root->rchild) {
    107. totalLength += depth * root->weight;
    108. }
    109. calculateEncodingLength(root->lchild, depth + 1, totalLength);
    110. calculateEncodingLength(root->rchild, depth + 1, totalLength);
    111. }
    112. int main()
    113. {
    114. Forest forest = (linkNode*)malloc(sizeof(linkNode));
    115. //森林的单链表包含一个头结点,头结点符号‘$'
    116. forest->tree = (BiTNode*)malloc(sizeof(BiTNode));
    117. forest->tree->data = '$';
    118. forest->next = NULL;
    119. createForest(forest);
    120. BiTree root = createHuffmanTree(forest);
    121. int totalLength = 0;
    122. calculateEncodingLength(root, 0, totalLength);
    123. printf("%d\n",totalLength);
    124. }

  • 相关阅读:
    狄拉克函数及其性质
    Elastic Search 浅浅认识 快速使用 keyword 和 text 的区别之处 spring boot 集成案例 es 增删改查
    云呐|动环监控设备维护与常见故障处理
    21、设计模式之备忘录模式(Memento)
    JVM之VisualVM工具的使用
    【【萌新的SOC学习之绪论】】
    如何发布一个 NPM 包
    使用HTML CSS制作静态网站【中秋节】
    Linux系统--多线程
    STL容器之list类
  • 原文地址:https://blog.csdn.net/laocooon/article/details/134234508