哈夫曼编码的首要思想就是,每次选出两个权重最小的结点,组成一颗新的二叉树,跟结点为两个结点的权重之和,左右孩子为刚选出来的两个结点。然后把这科树放回去,重新选择,直到剩下一颗树。
using namespace std;
typedef struct TNode {
char value;
int fre;
struct TNode* leftNode;
struct TNode* rightNode;
}TNode;
struct cmp//比较函数,用于优先队列构造最小堆
{
bool operator() (TNode *node1,TNode *node2)
{
return node1->fre>node2->fre;
}
};
int calWeight(TNode* root, int deep);
void del(TNode* root);
int main(void)
{
int n,fre;
char value;
while (cin>>n) {
priority_queue<TNode*, vector<TNode*>, cmp> queue;
for (int i = 0; i < n; ++i) {
cin >> value >> fre;
TNode* node = new TNode;
node->value = value;
node->fre = fre;
node->leftNode = NULL;
node->rightNode = NULL;
queue.push(node);
}
while (queue.size()>1) {
struct TNode* node1 = queue.top();
queue.pop();
struct TNode* node2 = queue.top();
queue.pop();
struct TNode* newNode = new TNode;
newNode->fre = node1->fre + node2->fre;
newNode->leftNode = node1;
newNode->rightNode = node2;
queue.push(newNode);
}
if (queue.size() == 1) {
struct TNode* root = queue.top();
queue.pop();
int result = calWeight(root, 0);
cout << result << endl;
del(root);
}
else {
cout << 0 << endl;
}
}
return 0;
}
//递归计算权重 B(T)=∑f(c)dT(c) 叶子节点权重乘以路径长度,累积
int calWeight(TNode* root, int deep) {
if (NULL == root)
return 0;
if ((NULL == root->leftNode) && (NULL == root->rightNode)) {
return deep * (root->fre);
}
int leftWieght = calWeight(root->leftNode,deep+1);
int rightWieght = calWeight(root->rightNode, deep + 1);
return leftWieght + rightWieght;
}
void del(TNode* root) {
if (NULL == root)
return;
del(root->leftNode);
del(root->rightNode);
delete(root);
}