注:实现Huffman编码是用贪心算法来实现的,证明Huffman的贪心选择和最优子结构很麻烦,我没有看懂(算法导论.中文版P234),这里只是给出了实现Huffman编码的实现代码。实现Huffman最好的数据结构时优先级队列(可以通过最小堆来实现)。整个算法的时间复杂度可以达到nlg(n),这里为了简单,没有实现最小堆,而使用的是STL中的set,通过实现正确的比较函数对象,每次可以取得优先级(字符出现频度最低)最大的值。但是这里的时间复杂度却提高了,因为操作set的选择时,时间复杂度时lgn,但是随着选择的,选择“未被访问的最高优先级的两个元素(flag=0)”的探测次数也为增大,平均探测次数是n/2,因此最后实现Huffman的时间复杂度将是n^2lg(n)。当然也可以通过记录每次选择元素时其在set中的位置(偏移量),下次选择时直接通过这个偏移量找到合适位置,探测的时间复杂度将会是1,最后实现Huffman的时间复杂度也可以达到nlog(n)。
n^2lg(n)的实现代码如下:
view plaincopy to clipboardprint?
#include <iostream>
#include <set>
using namespace std;
struct Node
{
int fu;//字符出现频度
int flag;//访问标识
struct Node *lc;//左孩子
struct Node *rc;//右孩子
};
struct compare_node//Node放在set<Node*>中的比较函数对象
{
bool operator()(const Node* node1,const Node *node2)const
{
return node1->fu < node2->fu;
}
};
set < Node *,compare_node> queue;
const int N = 6;
int s[N];//保存字符的编码
int f[N];//频度
struct Node *huffman()
{
int i = 0;
while(i<N-1)//一共需要N-1次合并操作(由叶子节点合并成具有左右孩子的非叶子节点)
{
Node *child[2];//找到两个出现频度最小的值
set< Node *,compare_node>::iterator it = queue.begin();
int lr = 0;
while(it!=queue.end() && lr <2)
{
if((*it)->flag ==0)//没有被访问过
{
child[lr] =*it;
(*it)->flag = 1;
lr ++;
}
it++;
}
Node *parent = new Node;
parent->flag = 0;
parent->lc = child[0];
parent->rc = child[1];
parent->fu = child[0]->fu + child[1]->fu;
queue.insert(parent);
i++;
}
int count = queue.size();
set <Node*>::reverse_iterator rit = queue.rbegin();
if(rit!=queue.rend())
return *rit;
else
return NULL;
}
//打印每个字符(频度值)的编码
void print(Node * root,int c)
{
if(root == NULL)
return;
else
{
if( root->lc != NULL)
{
s[c++] = 0;
print(root->lc,c);
}
if(root->rc!=NULL)
{
c--;
s[c++]=1;
print(root->rc,c);
}
//输出字符的编码
if(root->lc == NULL && root->rc == NULL)
{
cout << root->fu <<" ";
int i =0;
for(i=0;i<c;i++)
cout << s[i];
cout << endl;
}
}
}
int main()
{
int i =0;
Node *p = NULL;
for(i=0;i<N;i++)
{
cin>>f[i];
p = new Node;
p->flag = 0;
p->fu = f[i];
p->lc = NULL;
p->rc = NULL;
queue.insert(p);
}
Node *node = huffman();
print(node,0);
}
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/clearriver/archive/2009/08/19/4464514.aspx
分享到:
相关推荐
这是根据算法设计与分析的课程实验而编写的代码,完全可以使用,欢迎大家下载。
问题描述:在一个操场的四周摆放着n堆石子。现要将石子有次序地合并成一堆。规定每次至少选2堆最多选k堆石子合并成新的一堆,合并的费用为新的...试设计一个算法,计算出将n堆石子合并成一堆的最大总费用和最小总费用。
题目:在一个操场的四周摆放着n堆石子。现要将石子有次序的合并成一堆。规定每次至少选2堆最多选k堆石子合并成新的一堆,合并的...试设计一个算法,计算出将n堆石子合并成一堆的最大费用和最小费用。 可以直接运行。
huffman编码哈夫曼编码的matlab实现
文本文件压缩解压 vc工程 windows图形界面 大学计算机专业 数据结构 课程实验设计
通过“图片压缩编码”的编程实践,学习树、遍历二叉树、哈夫曼树、哈夫曼编码和他们的编程应用。 (1)掌握树的存储结构 (2)掌握二叉树的三种遍历方法 (3)掌握并理解Huffman树、Huffman编码等知识和应用 (4)掌握文件的...
利用matlab实现基于哈夫曼编码的信源编码实验
第8章贪心算法-Huffman算法,java考试参考资料,大家踊跃下载。
利用c++实现了Huffman编码,并对代码进行了注释,保证可读性。 {4,2,13,3,7,10,8,23,22,35,52,31} 下面是编码结果: 第1个数的huffman编码是:00000 第2个数的huffman编码是:000010 第3个数的huffman编码是:0110 ...
Huffman 编码是一种基于字符出现频率构建相应前缀码的无损数据压缩算法。 使用方法: 1. 需要安装 OpenCV 和 Numpy 库: pip install opencv-python numpy 2. 直接运行 main.py 脚本即可使用。 压缩原理: 1. 统计...
哈夫曼编码,运用matlab实现,原代码非常直观而且易懂。
Huffman编码(二叉树的应用)其中包含了源代码及实验截图
用VC实现的哈夫曼编码,对于已有文件,只能压缩ASCII码里面有的字符。
1. 分糖果 2. 钱币找零 3. 区间覆盖 1. 在一个非负整数 a 中,我们希望从中移除 k 个数字,让剩下的数字值最小,如何选择移 2. 假设有 n 个人
利用哈夫曼实现图片压缩,压缩比,哈夫曼编码(Huffman Coding),又称霍夫曼编码,是一种编码方式,哈夫曼编码是可变字长编码(VLC)的一种。Huffman于1952年提出一种编码方法,该方法完全依据字符出现概率来构造异字头...
用贪心算法求解Huffman编码,建立Huffman树,进行编码译码。
哈弗曼树实现 Huffman实现 哈夫曼实现 c++实现 使用方法 getCode:一个map, int> 的对象,该对象表示对ascii文件的统计数据,一个map, pair, int> > 的对象,该对象是编码后各个字符的对应的编码以及该编码的长度 ...
1.要求对文件进行Huffman编码的算法,以及对一编码文件进行解码的算法 2.熟练掌握二叉树的应用;具体要求如下: 最小冗余码/哈夫曼码
哈夫曼 huffman 编码 实验 附带完整的程序 加说明 保证能运行
数据结构课上,自己使用C++实现的huffman哈夫曼编码。有注释,较易理解。