[置顶] 算法导论之--------------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;
}

[置顶] 算法导论之--------------Huffman编码_第1张图片


你可能感兴趣的:(算法导论,Huffman,优先队列,huffman编码)