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

原创 2016年06月01日 15:14:13

优先队列内部一般是用堆来实现的。我们知道堆的插入、删除操作的时间复杂度都是 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;
}
版权声明:ShirleyPaul原创,未经博主允许不得转载

相关文章推荐

利用优先队列编写哈夫曼树和编码

利用“有序链表”来实现优先队列,链表元素按优先级递减。元素出列即出首元素,元素入列即将元素插入有序链表使其依然有序。本程序中,字符频率小则优先级高。 typedef int PQElemType...

POJ 2051 优先队列/小顶堆O(klog(n))轻松实现

#include typedef struct node { int ID; int period; long long time; }Node; Node heap[1005]; stati...

SDUT OJ 树-堆结构练习——合并果子之哈夫曼树 C++优先队列练习

今天做题跟同学学习了优先队列,瞬间感觉不错哦。就记下来了。。。以后复习用。。。。 题目描述  在一个果园里,多多已经将所有的果子打了下来,而且按果子的不同种类分成了不同的堆。多多决定把所有的果子合...

最小优先队列实现赫夫曼树 贪心策略

使用 最小优先队列存放要编码的key,和合并之后内部节点,注意最小优先队列,获得最小值时会把最小是删掉,下面是java实现。 package Algorithms; class MinQueue>{...

优先级队列实现哈夫曼树的编码和译码

//优先级队列实现的哈夫曼树的编码和译码 #include #include #include using namespace std; class Nod...

poj-3253-sdutoj-2127-哈夫曼树-优先队列

Description Farmer John wants to repair a small length of the fence around the pasture. He measures...

POJ 3253 Fence Repair(优先队列构造哈夫曼树)

割木板,割木板的长度就是花的钱。比如你要8 8 5 的木板,最简单的方式是把21的木板割成13,8,花费21,再把13割成5,8,花费13,共计34,当然也可以先割成16,5的木板,花费21,再把16...

哈夫曼树 --- 优先队列(C++STL)

数据结构实验之二叉树六:哈夫曼编码 Time Limit: 1000MS Memory Limit: 65536KB Submit Statistic Problem Description字符...

POJ 3253 采用优先队列 构造赫夫曼树

优先队列 基本操作: empty() 如果队列为空返回真 pop() 删除对顶元素 push() 加入一个元素 size() 返回优先队列中拥有的元素个数 top() 返回优先队列对顶元素...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)