问题描述:
给定一个文本中n个字符的出现频率。设计n个字符的哈夫曼编码。
输入
一个整数n,n<100,下面n行分别为n个字符及其出现频率
输出
所有字符的频率与其编码长度的乘积之和
示例测试集:
- 第1组
输入:
5 A 35 B 10 C 20 D 20 _ 15
输出:
225
- 第2组
输入:
3 x 20 Y 50 Z 5
输出:
100
整体思路:
用自定义类node实现存储
class node { public: string word; int weight; int lchild; int rchild; int parent; public: node(string a, int b) { word = a; weight = b; lchild = -1; rchild = -1; parent = -1; } node() {} };
将之后新建结点与当前结点都存入vector容器内
在 select()函数中实现每次挑出最小的两个数(min),并实现连接(connect)
特别需要注意的是 哈夫曼编码树 最后的结点数=数据结点*2-1
注意点:
int类型最大值 MAX 0x7fffffff
vector 自定义类 必须实现构造函数
printf中实现递归错误写法 将a值改变,这样无法实现遍历
void printf(int a) { cout << tree[a].weight << endl; if (tree[a].lchild != -1) { a=tree[a].lchild; printf(a); } if(tree[a].rchild != -1) { a=tree[a].rchild; printf(a); } }
源代码:
#include<iostream> #include<string> #include<vector> #define MAX 0x7fffffff using namespace std; class node { public: string word; int weight; int lchild; int rchild; int parent; public: node(string a, int b) { word = a; weight = b; lchild = -1; rchild = -1; parent = -1; } node() { } }; vector<node> tree; int leaf_n;//叶节点的个数 //结点结构 //选出没有父母且权重最小的结点 int min(int last) { int min = MAX; int mark = -1; for (int i = 0; i < tree.size(); i++) { if (tree[i].weight < min && tree[i].parent == -1 && i!=last) { min = tree[i].weight; mark = i; } } return mark; } //连接结点 void connect(int a, int b, int c) { tree[c].lchild = a;//小权重放在左边 tree[c].rchild = b; tree[a].parent = c; tree[b].parent = c; } //选择两个没有父母且权重最小的两个结点的方法实现 void select() { int min1, min2; for (int i = leaf_n; i<leaf_n * 2 - 1; i++) { min1 = min(-1); min2 = min(min1); if (min1 != -1 && min2 != -1) { tree.push_back(node(" ", tree[min1].weight + tree[min2].weight)); connect(min1, min2, i); } else { } } } /*void printf(int a) { cout << tree[a].weight << endl; if (tree[a].lchild != -1) { printf(tree[a].lchild); } if(tree[a].rchild != -1) { printf(tree[a].rchild); } }*/ int cal() { int temp; int total = 0; node a; for (int i = 0; i < leaf_n; i++) { a = tree[i]; temp = 0; while (a.parent != -1) { a = tree[a.parent]; temp++; } total += temp * tree[i].weight; } return total; } int main() { cin >> leaf_n; string word; int w; for (int i = 0; i < leaf_n; i++) { cin >> word; cin >> w; tree.push_back(node(word, w)); } select(); //printf(tree.size() - 1); cout << cal() << endl; system("pause"); return 0; }
文章来源: 哈夫曼编码问题