问题描述 :
内容:请参照二叉树的ADT模板,设计Huffman树的抽象数据类型。(由于该环境目前仅支持单文件的编译,故将所有内容都集中在一个源文件内。在实际的设计中,推荐将抽象类及对应的派生类分别放在单独的头文件中。参考教材、课件,以及网盘中的二叉树ADT原型文件,自行设计Huffman树的ADT。)
应用:要求设计一个算法,使用动态存储的方式,实现Huffman树的ADT。
提示:动态存储是指在新添加一个数据元素时,为它申请一个动态变量。删除一个数据元素时,释放该元素的存储空间。huffman树类的行为主要有两个:构造一棵haffuman树和获取叶子结点的Huffman编码。但由于树上的结点都是动态申请的,为此还需要一个析构函数。每个结点要保存的信息有4个:结点的值、结点的权值、左孩子指针、右孩子指针。
注意:为了保证你生成的哈夫曼树和题目的要求一致,需要遵循以下原则:
1、两个结点合并成一棵树时,权重小的结点为新树的左子树,权重大的结点为新树的右子树。
2、如果两个结点权重相等,则本来在左边的结点为新树的左子树。
3、新创建的树始终放在集合(森林)的最右边。
输入范例 :
5
d i a n w
7 5 2 4 9
输出范例 :
(27) (11) (16) i(5) (6) d(7) w(9) a(2) n(4)
(27) (11) i(5) (6) a(2) n(4) (16) d(7) w(9)
i(5) (11) a(2) (6) n(4) (27) d(7) (16) w(9)
i(5) a(2) n(4) (6) (11) d(7) w(9) (16) (27)
d:10
i:00
a:010
n:011
w:11
template<class T>
struct TreeNode {
int weight = 0;
T val;
int id = 0;
int flag = 1;
TreeNode* left;
TreeNode* right;
TreeNode() : val(0), left(nullptr), right(nullptr) {}
TreeNode(T x,int w=0) : val(x),weight(w), left(nullptr), right(nullptr) {}
TreeNode(T x, TreeNode* left, TreeNode* right) : val(x), left(left), right(right) {}
};
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
using namespace std;
template<class T>
TreeNode<T>* build(T empty) {
T val;
cin >> val;
if (val != empty) {
TreeNode<T>* node = new TreeNode<T>(val);
node->left = build<T>(empty);
node->right = build<T>(empty);
return node;
}
else {
return NULL;
}
}
#include <queue>
template<class T>
TreeNode<T>* buildlayer(T empty) {
string str;
getline(cin, str);
stringstream ss(str);
TreeNode<T>* head = new TreeNode<T>("");
queue< TreeNode<T>*>q;
q.push(head);
while (ss >> str) {
TreeNode<T>* obj = q.front();
q.pop();
if (str != empty) {
obj->val = str;
obj->flag = 1;
obj->left = new TreeNode<T>("");
obj->left->flag = 0;
obj->right = new TreeNode<T>("");
obj->right->flag = 0;
q.push(obj->left);
q.push(obj->right);
}
}
while (q.size()) {
q.front()->flag = 0;
q.pop();
}
return head;
}
template<class T>
void preorder(TreeNode<T>* tree, vector<TreeNode<T>*>& list) {
if (tree) {
if (tree->flag)list.push_back(tree);
preorder(tree->left, list);
preorder(tree->right, list);
}
}
template<class T>
void inorder(TreeNode<T>* tree, vector<TreeNode<T>*>& list) {
if (tree) {
inorder(tree->left, list);
if (tree->flag)list.push_back(tree);
inorder(tree->right, list);
}
}
template<class T>
TreeNode<T>* seek(TreeNode<T>* t, T target) {
if (!t)return NULL;
if (t->val == target)return t;
auto l = seek(t->left, target), r = seek(t->right, target);
if (l)return l;
else return r;
}
template<class T>
TreeNode<T>* seekparent(TreeNode<T>* t, T target) {
if (!t)return NULL;
if (t->val == target)return NULL;
if (t->left && t->left->val == target || t->right && t->right->val == target)
return t;
else {
auto l = seekparent(t->left, target), r = seekparent(t->right, target);
if (l)return l;
else return r;
}
}
template<class T>
void postorder(TreeNode<T>* tree, vector<TreeNode<T>*>& list) {
if (tree) {
postorder(tree->left, list);
postorder(tree->right, list);
if (tree->flag)list.push_back(tree);
}
}
template<class T>
void levelOrder(TreeNode<T>* tree, vector<TreeNode<T>*>& list) {
queue< TreeNode<T>*>q;
q.push(tree);
while (q.size()) {
list.push_back(q.front());
if (q.front()->left)q.push(q.front()->left);
if (q.front()->right)q.push(q.front()->right);
q.pop();
}
}
template<class T>
void out(TreeNode<T>* head) {
vector<TreeNode<T>*>pr, in, po, lv;
levelOrder(head, lv);
preorder(head, pr);
inorder(head, in);
postorder(head, po);
for (int i = 0; i < lv.size(); ++i) {
cout << lv[i]->val << "(" << lv[i]->weight << ")" << " ";
}
cout << endl;
for (int i = 0; i < pr.size(); ++i) {
cout << pr[i]->val<<"("<<pr[i]->weight<<")" << " ";
}
cout << endl;
for (int i = 0; i < in.size(); ++i) {
cout << in[i]->val << "(" << in[i]->weight << ")" << " ";
}
cout << endl;
for (int i = 0; i < po.size(); ++i) {
cout << po[i]->val << "(" << po[i]->weight << ")" << " ";
}
cout << endl;
}
#include<algorithm>
#include <unordered_map>
struct ch
{
string val;
int weight;
ch(string v = "", int w = 0) {
val = v;
weight = w;
}
};
vector<ch>rawchart;
vector<TreeNode<string>* > chart, pool;
bool cmp(TreeNode<string>* a, TreeNode<string>* b) {
if(a->weight!=b->weight)
return a->weight > b->weight;
return a->val < b->val;
}
TreeNode<string>* combine(TreeNode<string>* a, TreeNode<string>* b) {
auto res = new TreeNode<string>("", a->weight + b->weight);
if (a->weight == b->weight)
cout<<"";
if (a->weight < b->weight||(a->weight == b->weight&&a->val!="")) {
res->left = a;
res->right = b;
}
else {
res->left = b;
res->right = a;
}
//printf("now combine: %s(%d) and %s(%d)\n", a->val.c_str(), a->weight, b->val.c_str(), b->weight);
return res;
}
unordered_map<string, string>codes;
void dfs(TreeNode<string>* tree, string code) {
if (tree->val != "")codes[tree->val] = code;
if (tree->left)dfs(tree->left, code + "0");
if (tree->right)dfs(tree->right, code + "1");
}
int main() {
int n;
cin >> n;
TreeNode<string>* head = NULL;
for (int i = 0; i < n; ++i) {
string c;
cin >> c;
ch tmp(c);
rawchart.push_back(tmp);
}
for (int i = 0; i < n; ++i)
cin >> rawchart[i].weight;
for (int i = 0; i < n; ++i) {
chart.push_back(new TreeNode<string>(rawchart[i].val, rawchart[i].weight));
}
sort(chart.begin(), chart.end(),cmp);
pool.push_back(chart.back());
head = pool[0];
chart.pop_back();
while (chart.size()) {
if (chart.size()==1||pool[0]->weight <= ( chart[chart.size() - 2]->weight)) {
pool.push_back(chart.back());
chart.pop_back();
}
else {
auto newnode = combine(chart.back(), chart[chart.size() - 2]);
chart.pop_back();
chart.pop_back();
chart.push_back(newnode);
}
sort(chart.begin(), chart.end(), cmp);
//out(head);
//cout << endl;
if (pool.size() == 2) {
auto newnode = combine(pool[0], pool[1]);
pool.clear();
chart.push_back(newnode);
sort(chart.begin(), chart.end(), cmp);
pool.push_back(chart.back());
head = chart.back();
chart.pop_back();
//chart.push_back(newnode);
}
sort(chart.begin(), chart.end(), cmp);
}
out(head);
cout << endl;
dfs(head,"");
for (int i = 0; i < rawchart.size(); ++i) {
cout << rawchart[i].val << ":" << codes[rawchart[i].val] << endl;
}
return 0;
}
有疑问欢迎咨询.