算法导论之--------------Huffman编码

学习Huffman编码最大的收获是学会了STL中优先队列的使用以及在使用的时候要注意的问题:在使用自定义数据类型的时候,优先队列要重载自己的比较操作符。

关于Huffman树怎么讲解请看算法导论讲解,原理真的很简单,不过要写出完整的代码难点就在于优先队列的使用。不废话了啊,再次强调,想把原理弄清楚,请看算法导论,树上的讲解比网上什么垃圾讲解不知道清晰多少,一看就懂。-----------------终于可以上代码了。

//在优先级队列中存入指针类型的节点
#include<iostream>
#include<queue>
#include<string>
using namespace std;

class Comapre;
class Node
{
public:
	friend Comapre;
	int key;
	char ch;
	Node* left;
	Node* right;
public:
	Node(int num, char c) :key(num), ch(c), left(NULL), right(NULL){}
	//
	//bool lessthan(const Node* node) const
	//{
	//	return key>node->key;
	//}
};
class Comapre
{
public:
	//因为优先级队列中传递的指针,所以不能直接在Node类里重载比较运算符
	//大家去看看STL中优先级队列使用与heap之间的关系
	bool operator()(Node*node1, Node*node2)
	{
		//bool flag = node1->lessthan(node2);
		//return flag;
		return node1->key < node1->key;
	}
};
//使用优先级队列存储元素,优先级队列能保证队列最顶端的是按照键值key排列的最小的元素
Node* Huffman(priority_queue<Node*, vector<Node*>, Comapre> que)
{
	//重复将最顶端的两个元素拿出合并之后再放入队列中
	while (que.size()>1)
	{
		Node *node = new Node(0, 0);
		node->left = que.top();
		que.pop();

		node->right = que.top();
		que.pop();

		node->key = node->left->key + node->right->key;

		que.push(node);
	}

	return que.top();
}
//利用中序遍历的方法输出霍夫曼编码
//思路是每向左指一个节点s添加0,每向右指一个节点添加1,每迭代完一次要退出s最后一个元素
//用到了string的pop_back函数
void Inorder(Node* node, string s)
{
	if (node == NULL)
	{
		return;
	}
	else
	{
		if (node->left != NULL)
		{
			s += '0';
		}
		Inorder(node->left, s);

		if (node->left == NULL&&node->right == NULL)
		{
			cout << node->ch << "'s code is :";

			for (auto i : s)
				cout << i;
			cout << endl;
		}

		s.pop_back();

		if (node->right != NULL)
			s += '1';
		Inorder(node->right, s);
	}
}

//将开辟的空间清空,不然会导致内存泄露
void Delete(Node*node)
{
	if (node == NULL)
	{
		return;
	}
	Delete(node->left);
	Delete(node->right);
	delete node;
}

int main()
{
	string s;
	Node*n[6];
	n[0] = new Node(5, 'f');
	n[1] = new Node(9, 'e');
	n[2] = new Node(16, 'd');
	n[3] = new Node(12, 'c');
	n[4] = new Node(13, 'b');
	n[5] = new Node(45, 'a');

	priority_queue<Node*, vector<Node*>, Comapre>qu;
	int i;
	for (i = 0; i<6; i++)
	{
		qu.push(n[i]);
	}

	Node* R = Huffman(qu);
	Inorder(R, s);
	Delete(R);
	return 0;
}

时间: 2024-10-13 09:59:05

算法导论之--------------Huffman编码的相关文章

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

题意:有N个数,每次选2个数合并为1个数,操作的开销就是这个新的数.直到只剩下1个数,问最小总开销. 解法:合并的操作可以转化为二叉树上的操作[建模],每次选两棵根树合并成一棵新树,新树的根权值等于两棵合并前树的根权值和(也与Huffman编码的建立过程类似,选权值最小的两棵树). 这样总开销就是除了叶子结点的权值和  => 每个叶子结点的权值*层数(根节点层数为0)之和  => WPL(树的所有叶子节点的带权路径长度之和,即该节点到根节点路径长度与节点上权的乘积之和). 而Huffman树就

算法导论 学习资源

学习的过程会遇到些问题,发现了一些比较好的资源,每章都会看下别人写的总结,自己太懒了,先记录下别人写的吧,呵呵. 1  Tanky Woo的,每次差不多都看他的 <算法导论>学习总结 - 1.前言 <算法导论>学习总结 - 2.第一章 && 第二章 && 第三章 <算法导论>学习总结 - 3.第四章 && 第五章 <算法导论>学习总结 - 4.第六章(1) 堆排序 <算法导论>学习总结 - 5.第六

Jcompress: 一款基于huffman编码和最小堆的压缩、解压缩小程序

前言 最近基于huffman编码和最小堆排序算法实现了一个压缩.解压缩的小程序.其源代码已经上传到github上面: Jcompress下载地址 .在本人的github上面有一个叫Utility的repository,该分类下面有一个名为Jcompress的目录便是本文所述的压缩.解压缩小程序的源代码.后续会在Utility下面增加其他一些实用的小程序,比如基于socket的文件断点下载小程序等等.如果你读了此文觉得还不错,不防给笔者的github点个star, 哈哈.在正式介绍Jcompres

基于Huffman编码的压缩软件的Python实现

哈夫曼编码是利用贪心算法进行文本压缩的算法,其算法思想是首先统计文件中各字符出现的次数,保存到数组中,然后将各字符按照次数升序排序,挑选次数最小的两个元素进行连结形成子树,子树的次数等于两节点的次数之和,接着把两个元素从数组删除,将子树放入数组,重新排序,重复以上步骤.为了解压,在压缩时首先往文件中填入huffman编码的映射表的长度,该表的序列化字符串,编码字符串分组后最后一组的长度(编码后字符串长度模上分组长度),最后再填充编码后的字符串.本算法中以一个字节,8位作为分组长度,将编码后二进制

算法导论学习---红黑树具体解释之插入(C语言实现)

前面我们学习二叉搜索树的时候发如今一些情况下其高度不是非常均匀,甚至有时候会退化成一条长链,所以我们引用一些"平衡"的二叉搜索树.红黑树就是一种"平衡"的二叉搜索树,它通过在每一个结点附加颜色位和路径上的一些约束条件能够保证在最坏的情况下基本动态集合操作的时间复杂度为O(nlgn).以下会总结红黑树的性质,然后分析红黑树的插入操作,并给出一份完整代码. 先给出红黑树的结点定义: #define RED 1 #define BLACK 0 ///红黑树结点定义,与普通

Huffman 编码压缩算法

前两天发布那个rsync算法后,想看看数据压缩的算法,知道一个经典的压缩算法Huffman算法.相信大家应该听说过 David Huffman 和他的压缩算法—— Huffman Code,一种通过字符出现频率,Priority Queue,和二叉树来进行的一种压缩算法,这种二叉树又叫Huffman二叉树 —— 一种带权重的树.从学校毕业很长时间的我忘了这个算法,但是网上查了一下,中文社区内好像没有把这个算法说得很清楚的文章,尤其是树的构造,而正好看到一篇国外的文章<A Simple Examp

贪心算法-霍夫曼编码

霍夫曼编码是一种无损数据压缩算法.在计算机数据处理中,霍夫曼编码使用变长编码表对源符号(如文件中的一个字母)进行编码,其中变长编码表是通过一种评估来源符号出现机率的方法得到的,出现机率高的字母使用较短的编码,反之出现机率低的则使用较长的编码,这便使编码之后的字符串的平均长度.期望值降低,从而达到无损压缩数据的目的.例如,在英文中,e的出现机率最高,而z的出现概率则最低.当利用霍夫曼编码对一篇英文进行压缩时,e极有可能用一个比特来表示,而z则可能花去25个比特(不是26).用普通的表示方法时,每个

Huffman编码之文件的解/压缩

问题描述:           生活中文件压缩技术可谓随处可见,在数据的密集型传输中文件压缩是一项重要的实用性技术.例如:较大文件的下载,传输等.常见的文件压缩工具有winRAR,2345好压,快压(KuaiZip)等,这些工具已经开发的相当牛逼,但是作为入门级的程序员来说,不能只停留在观摩的立场上,扮演使用者的角色.有必要深入了解其底层的基础实现方式,掌握基础的文件压缩原理,所以在此将其视为一个小型项目列出,以供大家交流探讨,相互学习.... ★在此之前,先来说说什么是文件压缩,用以抛出一个基

算法导论学习---红黑树详解之插入(C语言实现)

前面我们学习二叉搜索树的时候发现在一些情况下其高度不是很均匀,甚至有时候会退化成一条长链,所以我们引用一些"平衡"的二叉搜索树.红黑树就是一种"平衡"的二叉搜索树,它通过在每个结点附加颜色位和路径上的一些约束条件可以保证在最坏的情况下基本动态集合操作的时间复杂度为O(nlgn).下面会总结红黑树的性质,然后分析红黑树的插入操作,并给出一份完整代码. 先给出红黑树的结点定义: #define RED 1 #define BLACK 0 ///红黑树结点定义,与普通的二