九、堆和优先队列---(5)优先队列解决哈夫曼编码
2016-04-29 14:57
323 查看
/*摘自计蒜客:http://www.jisuanke.com/course/35/6525
*优先队列解决哈夫曼编码
*当哈夫曼树上结点总个数大于 1 时,哈夫曼树的 WPL,等于树上除根结点之外的所有结点的权值之和。如果结点总个数为 1,则哈夫曼树的 WPL 即为根结点权值。
*每次从优先队列里取出两个权值最小的元素,累加元素权值后,将两个元素权值的和插入到优先队列里。重复上述操作,直到优先队列里剩下一个元素为止。如果n为1,则需要特殊处理。
*维护一个小根堆
*/
#include<iostream>
using namespace std;
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:一共有n个数,value代表权值,这里代表每个字符出现次数,ans记录最后的结果。
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 += 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;
}
*优先队列解决哈夫曼编码
*当哈夫曼树上结点总个数大于 1 时,哈夫曼树的 WPL,等于树上除根结点之外的所有结点的权值之和。如果结点总个数为 1,则哈夫曼树的 WPL 即为根结点权值。
*每次从优先队列里取出两个权值最小的元素,累加元素权值后,将两个元素权值的和插入到优先队列里。重复上述操作,直到优先队列里剩下一个元素为止。如果n为1,则需要特殊处理。
*维护一个小根堆
*/
#include<iostream>
using namespace std;
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:一共有n个数,value代表权值,这里代表每个字符出现次数,ans记录最后的结果。
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 += 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;
}
相关文章推荐
- 微信开发(二)天气
- linux下qt创建的窗口菜单项在左上方显示的问题
- spring3 jdbctemplate 注解实例
- 每天laravel-20160728| Genaerator command-6
- 一路成长的点点滴滴
- 线程带参数的例子
- 【HDU】 1532 Drainage Ditches
- WebStorm2016.1 破解 激活
- UILabel常用属性详解
- Servlet和JSP读书笔记(一)
- 内存管理:_CrtDumpMemoryLeaks和_CrtSetBreakAlloc
- Vuforia 在Unity 中失焦的问题
- 冒泡算法
- svn命令行使用总结(转载集合)
- 每天laravel-20160728| Genaerator command-6
- 操作系统开发系列—13.a.进程 ●
- 程序语言基础知识:Java引用与C指针的区别
- java创建文件和目录
- 如何利用matlab进行频谱分析
- 判断一个点在多边形内