哈夫曼树求权值

来源:互联网 发布:淘宝胶带母卷 编辑:程序博客网 时间:2024/06/13 09:53

  哈夫曼树的权值求法,根据需要我们要构造哈夫曼树,然后根据树求节点,这个肯定是很麻烦的,可以根据哈夫曼树的构造过程可以看出来每次都是取最小的两个树节点然后合并成一棵树,而权值有两种算法,第一个可以取所有的叶子节点,用叶子节点与路径的乘积的和,第二种就是可以取所有的非叶子节点的总和。使用优先队列的就是使用的第二种办法,选一个标记是否为叶子节点,不是叶子节点的权值相加即可,有几个需要注意的地方:第一个就是优先队列的使用,对于自定义的结构体优先队列需要重载"<"操作符,具体重载方法参考其他资料http://blog.csdn.net/qingtianweichong/article/details/10021781 ,第二个要注意的地方就是每次从队列取出来的是两个节点,而哈夫曼树的节点个数一定是奇数个(可以证明,简单的说就是每次都是通过两个节点合并成一棵树,父节点就是两个节点的权值和),所以使用队列操作时需要注意只剩一下一个节点,也就是根节点时不能取出两个节点。最后使用hdu 2527的一个很明显的题目做代码检验http://acm.hdu.edu.cn/showproblem.php?pid=2527,代码如下:

#include <iostream>#include <queue>const int MAX = 10e5 ;struct Node{int weight;bool IsLeaf;bool operator < (const Node &n1) const{return weight > n1.weight;}Node(){weight = 0;IsLeaf = true;}};int main(){int T;std::cin >> T;while(T--){int m;Node array[150];//记录权值用的std::cin >> m ;char str[MAX];std::cin >> str ;//std::cout << str <<std::endl; int i =0;while(str[i] != '\0'){array[str[i]].weight ++ ;array[str[i]].IsLeaf = true;i ++;}std::priority_queue<Node>  Q;for(i= 'a' ; i <= 'z' ;i++){if(array[i].weight >=1 ) Q.push(array[i]);}int sum = 0;while(Q.size() > 1){Node temp1 = Q.top();Q.pop();Node temp2 ;//if(!Q.empty())//{temp2 = Q.top();Q.pop();//}if( !temp1.IsLeaf )sum += temp1.weight;if( !temp2.IsLeaf )sum += temp2.weight;Node temp3;temp3.weight = temp1.weight+temp2.weight;temp3.IsLeaf = false;Q.push(temp3);//if(Q.size() > 1)//{//Q.push(temp3);//sum += temp3.weight;//}}if(!Q.empty()){Node temp = Q.top();sum += temp.weight ;}//std::cout << sum <<std::endl;if(sum <= m)std::cout << "yes" <<std::endl;elsestd::cout << "no" <<std::endl;}}