您的位置:首页 > 其它

小顶堆_优先队列 ,实现哈夫曼树的WPL求值

2016-06-01 15:14 288 查看
优先队列内部一般是用堆来实现的。我们知道堆的插入、删除操作的时间复杂度都是 O(logN)O(logN),自然优先队列的插入、删除操作的时间复杂度也都是 O(logN)O(logN)。堆中的堆顶元素就是优先队列的队首元素。

对于大根堆实现的优先队列,总是优先级高的元素先被删除;相对的,对于小根堆实现的优先队列,总是优先级低的元素先被删除。对于后者,我们也称之为优先队列。

优先队列可以用于解决哈夫曼编码问题。这个问题我们在二叉树一章最后给大家介绍过噢,后面的课程中我们会为大家讲解如何用优先队列来解决它。此外,优先队列还能解决任务调度问题,例如操作系统的进程调度问题。

在 C++ 的 STL 里,有封装好的优先队列 priority_queue,它包含在头文件 里噢。优先级可以自己定义,默认优先级是权值大的元素优先级高。优先队列是一种用途广泛的数据结构,它能巧妙高效的解决很多其他数据结构不容易解决的问题

《树和二叉树》最后有介绍哈夫曼编码问题,对于一个已知的字符串,我们要计算字符串进行哈夫曼编码后的长度,即哈夫曼树的带权路径长度 WPL(Weighted Path Length),也就是每个叶子结点到根结点的距离乘以叶子结点权值结果之和。

当哈夫曼树上结点总个数大于 1 时,哈夫曼树的 WPL,等于树上除根结点之外的所有结点的权值之和。如果结点总个数为 1,则哈夫曼树的 WPL 即为根结点权值。例如上面的例子里:

WPL=16+10+9+7+5+5+4+5+3+4+2+3+2+2+2+1+1+1=82

利用小顶堆_优先队列 ,实现哈夫曼树的WPL求值

#include<iostream>
using namespace std;

//从优先队列中选出权值最小的两个pop,将权值相加得到新节点,权值和累加
//插入队列中,直至队列中只有一个元素,WPL求出
class Heap {
private:
int *data, size;
public:
Heap(int length_input) {
data = new int[length_input];
size = 0;
}
~Heap() {
delete[] data;
}
void push(int value) {
data[size] = value;
int current = size;
int father = (current - 1) / 2;
while (data[current] < data[father]) {
swap(data[current], data[father]);
current = father;
father = (current - 1) / 2;
}
size++;
}
int top() {
return data[0];
}
void update(int pos, int n) {
int lchild = 2 * pos + 1, rchild = 2 * pos + 2;
int max_value = pos;
if (lchild < n && data[lchild] < data[max_value]) {
max_value = lchild;
}
if (rchild < n && data[rchild] < data[max_value]) {
max_value = rchild;
}
if (max_value != pos) {
swap(data[pos], data[max_value]);
update(max_value, n);
}
}
void pop() {
swap(data[0], data[size - 1]);
size--;
update(0, size);
}
int heap_size() {
return size;
}
};
int main() {
//n个数;value权值;
int n,value,ans=0;
cin>>n;
Heap heap(n);
for(int i=1;i<=n;i++){
cin>>value;
heap.push(value);
}
if(n==1){
ans=ans+heap.top();
}
while(heap.heap_size()>1){
int a=heap.top();
heap.pop();
int b=heap.top();
heap.pop();

ans=ans+a+b;
heap.push(a+b);
}
cout<<ans<<endl;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息