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

来源:互联网 发布:mathcad读取数据 编辑:程序博客网 时间:2024/05/22 06:39

优先队列内部一般是用堆来实现的。我们知道堆的插入、删除操作的时间复杂度都是 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;}
0 0