学习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