huffman编码中WPL等于没个结点到根结点的距离乘结点权值的总和,但我们也可以用另一种方法求WPL:如果huffman树只有一个结点,则WPL为根结点权值,否则WPL等于除了根结点以外的所有结点的权值之和。
我们可以用优先队列/堆实现这个过程:
1 //用优先队列求huffman编码中的WPL 2 #include <iostream> 3 using std::cin; 4 using std::cout; 5 using std::endl; 6 using std::swap; 7 8 template <typename Type> class Heap { 9 private: 10 Type *data; 11 int size; 12 void update(int pos, int n) { 13 int lchild = 2 * pos + 1, rchild = 2 * pos + 2; 14 int max_value = pos; 15 if (lchild < n && data[lchild] < data[max_value]) { 16 max_value = lchild; 17 } 18 if (rchild < n && data[rchild] < data[max_value]) { 19 max_value = rchild; 20 } 21 if (max_value != pos) { 22 swap(data[pos], data[max_value]); 23 update(max_value, n); 24 } 25 } 26 public: 27 Heap(int length_input) { 28 data = new Type[length_input]; 29 size = 0; 30 } 31 ~Heap() { 32 delete[] data; 33 } 34 void push(Type value) { 35 data[size] = value; 36 int current = size; 37 int father = (current - 1) / 2; 38 while (data[current] < data[father]) { 39 swap(data[current], data[father]); 40 current = father; 41 father = (current - 1) / 2; 42 } 43 size++; 44 } 45 Type top() { 46 return data[0]; 47 } 48 void pop() { 49 swap(data[0], data[size - 1]); 50 size--; 51 update(0, size); 52 } 53 int heap_size() { 54 return size; 55 } 56 }; 57 int main() { 58 int n,value,ans=0; 59 cin>>n; 60 Heap<int> heap(n); 61 for(int i=1;i<=n;i++){ 62 cin>>value; 63 heap.push(value); 64 } 65 if(n==1){ 66 ans+=heap.top(); 67 } 68 while(heap.heap_size()>1){ 69 int a=heap.top(); 70 heap.pop(); 71 int b=heap.top(); 72 heap.pop(); 73 //将小根堆最前面的两个元素,即最小的两个元素合并 74 //并把合成的树押回队列中 75 ans=ans+a+b; 76 heap.push(a+b); 77 } 78 cout<<ans<<endl; 79 return 0; 80 }
时间: 2024-11-05 21:57:49