1. 优先队列小析

     优先队列的模板: template <class T, class Container = vector<T>,class Compare = less<typename Container::value_type> > class priority_queue;

 可以看出priority_queue的模板声明带有三个参数,T为数据类型,Container为保存数据的容器,,Compare为元素比较方式,其中Container必须是用数组实现的容器,比如vector,deque,不能用list.STL里面容器默认用的是 vector. 比较方式默认用 operator< ,所以如果你把后面俩个参数 缺省的话,优先队列就是大顶堆。如果要用到小顶堆,则一般要把模板的三个参数都带进去。STL里面定义了一个仿函数 greater<Type>,对于基本类型可以用这个仿函数声明小顶堆。引用自(DanielWang_).
  在求解Huffman编码里面,我们需要用到小顶堆性质,而且元素还是指针元素.因此我们使用如下的方式定义优先队列,把模板的三个参数都带进去,并且还自定义了仿函数.

typedef struct HTNode{
char c;
unsigned int freq;
HTNode *lchild, *rchild; //构造函数
HTNode(char key='\0', unsigned int fr=, HTNode *l=NULL, HTNode *r=NULL):
c(key),freq(fr),lchild(l),rchild(r){}; }HTNode,*pNode; //重载优先队列里的比较运算符
struct cmp{
bool operator()(pNode node1, pNode node2){
return node1->freq > node2->freq;
}
}; //含有指针类型的优先队列
priority_queue<pNode, vector<pNode>, cmp> pq;

  2. 具体实现代码 


在打印Huffman 编码的时候,还用到了string的一个函数,erase,即删除某个字符.因为end()返回string的最后一个字符的下一个位置,那么就可以用如下的方法删除最后一个字符.
str.erase(str.end()-1); //删除最后一个字符
 
*************************************************************************
> File Name: Huffman_code_pg.cpp
> Author: He Xingjie
> Mail: gxmshxj@.com
> Created Time: 2014年06月06日 星期五 08时57分01秒
> Description:
************************************************************************/
#include<iostream>
#include<queue>
#include<vector>
#include<cstdio>
#include<stack> using namespace std; typedef struct HTNode{
char c;
unsigned int freq;
HTNode *lchild, *rchild; //构造函数
HTNode(char key='\0', unsigned int fr=, HTNode *l=NULL, HTNode *r=NULL):
c(key),freq(fr),lchild(l),rchild(r){}; }HTNode,*pNode; //重载优先队列里的比较运算符
struct cmp{
bool operator()(pNode node1, pNode node2){
return node1->freq > node2->freq;
}
}; //含有指针类型的优先队列
priority_queue<pNode, vector<pNode>, cmp> pq; void HuffmanCode(int n)
{
pNode l, r; //从优先队列中找出优先级最小的两个元素,合并,并
//把它加入到优先队列中
while (pq.size() > )
{
pNode z = new HTNode; l = pq.top();
pq.pop();
r = pq.top();
pq.pop(); z->lchild = l;
z->rchild = r;
z->freq = l->freq + r->freq; pq.push(z);
}
} void PrintCode(pNode t, string str)
{
//中序递归遍历HuffmanTree求解HuffmanCode
if (t == NULL)
return;
if (t->lchild)
{
str += '';
PrintCode(t->lchild, str);
} //叶子节点
if (t->lchild == NULL && t->rchild == NULL)
{
cout<<t->c<<"'s code: "<<str<<endl;
} str.erase(str.end()-); //删除最后一个字符 if (t->rchild)
{
str += '';
PrintCode(t->rchild, str);
}
} void DFS(HTNode *t)
{
HTNode *node;
stack<pNode, vector<pNode> > pstack; pstack.push(t);
node = pstack.top();
pstack.pop(); while (pstack.size() > )
{
if (node->lchild)
{
pstack.push(node->lchild);
node = node->lchild;
}
else if(node->rchild)
{
pstack.push(node->rchild);
node = node->rchild;
}
else
{
printf("%d ", node->freq);
node = pstack.top();
pstack.pop();
}
}
} int main()
{
int n, i;
FILE *fp;
char tmp;
string str; fp = fopen("in.txt", "r");
if (fp ==NULL)
{
printf("fopen error!\n");
return -;
} //输入大小
fscanf(fp, "%d", &n);
fscanf(fp, "%c", &tmp); //输入数据
for (i=; i<n; i++)
{
char c;
int freq;
pNode p = new HTNode; fscanf(fp, "%c%d", &c, &freq);
p->c = c;
p->freq = freq; fscanf(fp, "%c", &tmp); pq.push(p);
} HuffmanCode(n);
PrintCode(pq.top(), str); return ;
}

 参考:

http://www.cplusplus.com/reference/queue/priority_queue/?kw=priority_queue

http://blog.csdn.net/liuzhanchen1987/article/details/7856893

http://blog.csdn.net/daniel_ustc/article/details/17613359

优先队列求解Huffman编码 c++的更多相关文章

  1. 优先队列实现Huffman编码

    首先把所有的字符加入到优先队列,然后每次弹出两个结点,用这两个结点作为左右孩子,构造一个子树,子树的跟结点的权值为左右孩子的权值的和,然后将子树插入到优先队列,重复这个步骤,直到优先队列中只有一个结点 ...

  2. 【uva 10954】Add All(算法效率--Huffman编码+优先队列)

    题意:有N个数,每次选2个数合并为1个数,操作的开销就是这个新的数.直到只剩下1个数,问最小总开销. 解法:合并的操作可以转化为二叉树上的操作[建模],每次选两棵根树合并成一棵新树,新树的根权值等于两 ...

  3. Huffman编码

    #define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <cstdio> #include <cstri ...

  4. 【数据压缩】Huffman编码

    1. 压缩编码概述 数据压缩在日常生活极为常见,平常所用到jpg.mp3均采用数据压缩(采用Huffman编码)以减少占用空间.编码\(C\)是指从字符空间\(A\)到码字表\(X\)的映射.数据压缩 ...

  5. Huffman编码(Huffman树)

    [0]README 0.1) 本文总结于 数据结构与算法分析, 源代码均为原创, 旨在 理解 "Huffman编码(Huffman树)" 的idea 并用源代码加以实现: 0.2) ...

  6. UVA 10954 Add All 全部相加 (Huffman编码)

    题意:给你n个数的集合,每次选两个删除,把它们的和放回集合,直到集合的数只剩下一个,每次操作的开销是那两个数的和,求最小开销. Huffman编码.Huffman编码对于着一颗二叉树,这里的数对应着单 ...

  7. 用优先队列构造Huffman Tree及判断是否为最优编码的应用

    前言 我们知道,要构造Huffman Tree,每次都要从堆中弹出最小的两个权重的节点,然后把这两个权重的值相加存放到新的节点中,同时让这两个节点分别成为新节点的左右儿子,再把新节点插入到堆中.假设节 ...

  8. [老文章搬家] 关于 Huffman 编码

    按:去年接手一个项目,涉及到一个一个叫做Mxpeg的非主流视频编码格式,编解码器是厂商以源代码形式提供的,但是可能代码写的不算健壮,以至于我们tcp直连设备很正常,但是经过一个UDP数据分发服务器之后 ...

  9. Huffman编码实现电文的转码与译码

    //first thing:thanks to my teacher---chenrong      Dalian Maritime university /* 构造Huffman Tree思路: ( ...

随机推荐

  1. Magcodes.WeiChat——通过CsvFileResult以及DataAnnotations实现导出CSV文件

    我们先来看看效果图: 从上图中可以看出,导出的文件中列名与表格名称保持一致,并且忽略了某些字段. 相关代码实现 我们来看相关代码: 页面代码: @using (Html.BeginForm(" ...

  2. 使用NHibernate(8)-- 延迟加载

    1,延迟加载. 延迟加载,即用到的时候再加载数据.这种机制是非常有情怀的,比如一篇中的用户实体有标签.问题等导航属性,如果只是用到用户名去查询整个实体,则把相关的标签和问题也都加载,性能会比较低.而有 ...

  3. ASP.NET MVC请求处理管道生命周期的19个关键环节(7-12)

    在上一篇"ASP.NET MVC请求处理管道生命周期的19个关键环节(1-6) ",体验了1-6关键环节,本篇继续. ⑦根据IsapiWorkerRequest对象,HttpRun ...

  4. jquery简单笔记(1) - 基础记录

    一.dom对象及jquery对象相互转换 jquery对象转换成dom对象,即 [index] 和 get(index) 第一种方式: var $j = $('#id'); // jquery对象 v ...

  5. canvas/CSS实现仪表盘效果

    手机上看比较虚 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <t ...

  6. Nagios学习笔记二:Nagios概述

    1.简介 Nagios是插件式的结构,它本身没有任何监控功能,所有的监控都是通过插件进行的,因此其是高度模块化和富于弹性的.Nagios监控的对象可分为两类:主机和服务.主机通常指的是物理主机,如服务 ...

  7. atitit.重装系统需要备份的资料总结 o84..

    atitit.重装系统需要备份的资料总结 o84.. 这里我的系统装在C盘..所以需要备份C盘的东西就好了.. 1.DESKTOP,这个目录要备份.如果重要资料 2.docume nt,这个需要..W ...

  8. atitit groovy 总结java 提升效率

    atitit groovy 总结java 提升效率 #---环境配置 1 #------安装麻烦的 2 三.创建groovy项目 2 3.  添加 Groovy 类 2 4.  编译运行groovy类 ...

  9. paip.php 5.0 5.3 5.4 5.5 -6.0的新特性总结与比较

    paip.php 5.0 5.3 5.4  5.5 -6.0的新特性总结与比较 PHP5的新特性 2 · 对象的参照过渡是默认的(default) 3 · 引入访问属性的限制 3 · 引入访问方法的限 ...

  10. paip.调试js 查看元素事件以及事件断点

    paip.调试js  查看元素事件以及事件断点 ff 26 +firebug 查看不出来.. 360 ,虽然也是chrome 基础,但是开发工具烂阿,也是显示不出来.. 作者Attilax  艾龙,  ...