赞
踩
基于哈夫曼树的规则生成哈夫曼树,其中用到了常见的二叉树生成逻辑,最后中序遍历使用递归实现。
- #include <iostream>
- #include <algorithm>
- #include <list>
-
- using namespace std;
-
- // 哈夫曼树节点
- struct halfman_tree_node
- {
- halfman_tree_node *down_left;
- halfman_tree_node *down_right;
- halfman_tree_node *parent;
- int value;
- };
-
- /// @brief 二叉树中序遍历
- /// @param tnode
- static void halfman_tree_middle_print(halfman_tree_node *tnode)
- {
- if (tnode == nullptr)
- {
- return;
- }
-
- halfman_tree_middle_print(tnode->down_left); // left
- cout << tnode->value << " "; // middle
- halfman_tree_middle_print(tnode->down_right); // right
- }
-
- // 生成哈夫曼树
- static void HuaWei_OD_test26(void)
- {
- int tnode_cnt;
- cin >> tnode_cnt;
-
- list<int> tnode_weight_list;
- for (int i = 0; i < tnode_cnt; i++)
- {
- int tmp;
- cin >> tmp;
- tnode_weight_list.push_back(tmp);
- }
-
- list<halfman_tree_node *> halfman_tree_list;
-
- // 第一次升序
- tnode_weight_list.sort();
-
- while (tnode_weight_list.size() >= 2)
- {
- // 找到最小的两个元素
- auto small_value1 = tnode_weight_list.begin(); // 最小
- auto small_value2 = tnode_weight_list.begin(); // 倒数第二小
- small_value2++;
-
- // 将两个元素合并为一个新元素
- int new_node_value = *small_value1 + *small_value2;
- halfman_tree_node *new_tnode = new halfman_tree_node;
- new_tnode->value = new_node_value;
- new_tnode->parent = nullptr;
-
- // 刚开始没有tnode,构建两个tnode
- if (halfman_tree_list.size() < 2)
- {
- halfman_tree_node *left_tnode = new halfman_tree_node;
- left_tnode->down_left = nullptr;
- left_tnode->down_right = nullptr;
- left_tnode->value = *small_value1;
-
- halfman_tree_node *right_tnode = new halfman_tree_node;
- right_tnode->down_left = nullptr;
- right_tnode->down_right = nullptr;
- right_tnode->value = *small_value2;
-
- new_tnode->down_left = left_tnode;
- new_tnode->down_right = right_tnode;
-
- left_tnode->parent = new_tnode;
- right_tnode->parent = new_tnode;
-
- halfman_tree_list.push_back(left_tnode);
- halfman_tree_list.push_back(right_tnode);
- }
- else
- {
- // 只需要申请一个新的tnode
- halfman_tree_node *x_tnode = new halfman_tree_node;
- x_tnode->down_left = nullptr;
- x_tnode->down_right = nullptr;
-
- // 此时halfman_tree_list的最后一个元素是目前的最长节点顶部
- auto current_top = halfman_tree_list.back();
-
- // 比较current_top节点的权重,和当前最小的权重来选择哪一个元素构建一个新的tnode
- if (current_top->value >= *small_value1)
- {
- x_tnode->value = *small_value1;
- new_tnode->down_left = x_tnode; // 更新顶部
- new_tnode->down_right = current_top;
- }
- else
- {
- x_tnode->value = *small_value2;
- new_tnode->down_left = current_top; // 更新顶部
- new_tnode->down_right = x_tnode;
- }
-
- x_tnode->parent = new_tnode;
- current_top->parent = new_tnode;
-
- halfman_tree_list.push_back(x_tnode);
- }
-
- halfman_tree_list.push_back(new_tnode); // 目前的顶部节点
-
- tnode_weight_list.pop_front(); // 权重列表去掉最小元素
- tnode_weight_list.pop_front(); // 权重列表去掉第二小元素
-
- tnode_weight_list.push_front(new_node_value); // 加入新的权重元素
- tnode_weight_list.sort(); // 重新升序排列
- }
-
- // 到这里说明tnode_weight_list只有一个权重,也就是根节点的权重
- // 也就意味着halfman_tree_list最后一个元素是根节点
-
- // 开始进行中序遍历
- auto root = halfman_tree_list.back(); // 根节点
-
- halfman_tree_middle_print(root);
-
- // 清理内存
- for (const auto &tnode : halfman_tree_list)
- {
- delete tnode;
- }
- }
-
- int main()
- {
- HuaWei_OD_test26();
- return 0;
- }

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。