#include<bits/stdc++.h>
using namespace std;
struct HTnode{
int w; //weight
int father; // father = -1 表示没有父节点
HTnode(int w,int fath = -1):w(w),father(fath){ };
};
struct Cmp{
bool operator()(const HTnode* a, const HTnode* b){
return a->w > b->w;
}
};
vector<HTnode*> createHT(vector<int>& weights); //返回建好的 父节点表示法 的 哈夫曼树
int getPathVal(vector<HTnode*>& HTnodes, int n);
int main(){
vector<int>weights; int x;
// given an array of num, representing the weight of each node.
while(cin>>x){
weights.push_back(x);
}
vector<HTnode*> HTnodes = createHT(weights);
cout<<getWPL(HTnodes, weights.size())<<endl; //第二个参数表示有多少个叶子节点
return 0;
}
vector<HTnode*> createHT(vector<int>& weights){
priority_queue<HTnode*,vector<HTnode*>,Cmp>pq; //小根堆,每次弹出最小权值节点
int n = weights.size();
vector<HTnode*> HTnodes(2*n - 1); // n 个叶子节点,n-1个合并节点 [0..n-1]为叶子节点
// 建 叶子节点
for(int i=0;i<n;i++){
HTnodes[i] = new HTnode(weights[i]);
pq.push(HTnodes[i]);
}
//建 合并节点
for(int i=n;i<2*n-1;i++){
HTnode *a, *b;
a = pq.top(); pq.pop();
b = pq.top(); pq.pop();
HTnodes[i] = new HTnode(a->w + b->w);
a->father = i; b->father = i;
pq.push(HTnodes[i]);
}
return HTnodes;
}
int getWPL(vector<HTnode*>& HTnodes, int n){
int ans = 0;
for(int i=0;i<n;i++){ //收集 n 个叶子结点的WPL
int val = HTnodes[i]->w; int cur = i;
while(HTnodes[i]->father != -1){ //路径长,i向上到达树根
ans += val;
i = HTnodes[i]->father;
}
i = cur; //恢复 i
}
return ans;
}
父节点表示法求哈夫曼树WPL
最新推荐文章于 2024-07-21 13:38:21 发布