当前位置:   article > 正文

2024年华为OD机试真题-生成哈夫曼树 C/C++解法_华为od 哈夫曼树

华为od 哈夫曼树

基于哈夫曼树的规则生成哈夫曼树,其中用到了常见的二叉树生成逻辑,最后中序遍历使用递归实现。

  1. #include <iostream>
  2. #include <algorithm>
  3. #include <list>
  4. using namespace std;
  5. // 哈夫曼树节点
  6. struct halfman_tree_node
  7. {
  8. halfman_tree_node *down_left;
  9. halfman_tree_node *down_right;
  10. halfman_tree_node *parent;
  11. int value;
  12. };
  13. /// @brief 二叉树中序遍历
  14. /// @param tnode
  15. static void halfman_tree_middle_print(halfman_tree_node *tnode)
  16. {
  17. if (tnode == nullptr)
  18. {
  19. return;
  20. }
  21. halfman_tree_middle_print(tnode->down_left); // left
  22. cout << tnode->value << " "; // middle
  23. halfman_tree_middle_print(tnode->down_right); // right
  24. }
  25. // 生成哈夫曼树
  26. static void HuaWei_OD_test26(void)
  27. {
  28. int tnode_cnt;
  29. cin >> tnode_cnt;
  30. list<int> tnode_weight_list;
  31. for (int i = 0; i < tnode_cnt; i++)
  32. {
  33. int tmp;
  34. cin >> tmp;
  35. tnode_weight_list.push_back(tmp);
  36. }
  37. list<halfman_tree_node *> halfman_tree_list;
  38. // 第一次升序
  39. tnode_weight_list.sort();
  40. while (tnode_weight_list.size() >= 2)
  41. {
  42. // 找到最小的两个元素
  43. auto small_value1 = tnode_weight_list.begin(); // 最小
  44. auto small_value2 = tnode_weight_list.begin(); // 倒数第二小
  45. small_value2++;
  46. // 将两个元素合并为一个新元素
  47. int new_node_value = *small_value1 + *small_value2;
  48. halfman_tree_node *new_tnode = new halfman_tree_node;
  49. new_tnode->value = new_node_value;
  50. new_tnode->parent = nullptr;
  51. // 刚开始没有tnode,构建两个tnode
  52. if (halfman_tree_list.size() < 2)
  53. {
  54. halfman_tree_node *left_tnode = new halfman_tree_node;
  55. left_tnode->down_left = nullptr;
  56. left_tnode->down_right = nullptr;
  57. left_tnode->value = *small_value1;
  58. halfman_tree_node *right_tnode = new halfman_tree_node;
  59. right_tnode->down_left = nullptr;
  60. right_tnode->down_right = nullptr;
  61. right_tnode->value = *small_value2;
  62. new_tnode->down_left = left_tnode;
  63. new_tnode->down_right = right_tnode;
  64. left_tnode->parent = new_tnode;
  65. right_tnode->parent = new_tnode;
  66. halfman_tree_list.push_back(left_tnode);
  67. halfman_tree_list.push_back(right_tnode);
  68. }
  69. else
  70. {
  71. // 只需要申请一个新的tnode
  72. halfman_tree_node *x_tnode = new halfman_tree_node;
  73. x_tnode->down_left = nullptr;
  74. x_tnode->down_right = nullptr;
  75. // 此时halfman_tree_list的最后一个元素是目前的最长节点顶部
  76. auto current_top = halfman_tree_list.back();
  77. // 比较current_top节点的权重,和当前最小的权重来选择哪一个元素构建一个新的tnode
  78. if (current_top->value >= *small_value1)
  79. {
  80. x_tnode->value = *small_value1;
  81. new_tnode->down_left = x_tnode; // 更新顶部
  82. new_tnode->down_right = current_top;
  83. }
  84. else
  85. {
  86. x_tnode->value = *small_value2;
  87. new_tnode->down_left = current_top; // 更新顶部
  88. new_tnode->down_right = x_tnode;
  89. }
  90. x_tnode->parent = new_tnode;
  91. current_top->parent = new_tnode;
  92. halfman_tree_list.push_back(x_tnode);
  93. }
  94. halfman_tree_list.push_back(new_tnode); // 目前的顶部节点
  95. tnode_weight_list.pop_front(); // 权重列表去掉最小元素
  96. tnode_weight_list.pop_front(); // 权重列表去掉第二小元素
  97. tnode_weight_list.push_front(new_node_value); // 加入新的权重元素
  98. tnode_weight_list.sort(); // 重新升序排列
  99. }
  100. // 到这里说明tnode_weight_list只有一个权重,也就是根节点的权重
  101. // 也就意味着halfman_tree_list最后一个元素是根节点
  102. // 开始进行中序遍历
  103. auto root = halfman_tree_list.back(); // 根节点
  104. halfman_tree_middle_print(root);
  105. // 清理内存
  106. for (const auto &tnode : halfman_tree_list)
  107. {
  108. delete tnode;
  109. }
  110. }
  111. int main()
  112. {
  113. HuaWei_OD_test26();
  114. return 0;
  115. }

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号