霍夫曼算法的实现。
#ifndef __CHUFFMANCODE__H #define __CHUFFMANCODE__H #include <iostream> #include <string> #include <functional> #include <queue> //哈夫曼编码 struct TreeNode { std::string strName; int nFrequence; // 出现的频率 int nWight; // 权值 TreeNode* pLeftTree; // 左子树 TreeNode* pRightTree; // 右子树 TreeNode() { strName = ""; nFrequence = 0; nWight = 0; pLeftTree = nullptr; pRightTree = nullptr; } }; class cmp { public: cmp(TreeNode* pNode) : m_pNode(pNode) {} bool operator< (const cmp& rhs) const { return m_pNode->nWight > rhs.m_pNode->nWight; } public: TreeNode* m_pNode; }; class CHuffmanCode { public: CHuffmanCode(); ~CHuffmanCode(); public: void InsertNode(std::string strName, int nFrequence); void Generater(); // 生成哈夫曼树 void PrintHuffmanCode(); // 打印编码 private: void DeleteTree(TreeNode*& pNode); void PrintHuffmanCode(TreeNode* pNode, std::queue<std::string>& strQueue); private: TreeNode* m_pRoot; // 最终生成的哈夫曼树 std::priority_queue<cmp> m_queue; // 最小堆 }; #endif
#include "HuffmanCode.h" CHuffmanCode::CHuffmanCode() { } CHuffmanCode::~CHuffmanCode() { DeleteTree(m_pRoot); } void CHuffmanCode::InsertNode(std::string strName, int nFrequence) // 为简单起见,由调用者保证不重复 { TreeNode* pNode = new TreeNode; pNode->strName = strName; pNode->nFrequence = nFrequence; pNode->nWight = nFrequence; m_queue.push(pNode); } void CHuffmanCode::Generater() { TreeNode* pNode = nullptr; while (!m_queue.empty()) { pNode = m_queue.top().m_pNode; m_queue.pop(); if (m_queue.empty()) break; TreeNode* pSecond = m_queue.top().m_pNode; m_queue.pop(); TreeNode* pNew = new TreeNode; // 生成新的节点 pNew->pLeftTree = pNode; pNew->pRightTree = pSecond; pNew->nWight = pNew->pLeftTree->nWight + pNew->pRightTree->nWight; m_queue.push(pNew); } m_pRoot = pNode; } void CHuffmanCode::DeleteTree(TreeNode*& pNode) { if (!pNode) return; DeleteTree(pNode->pLeftTree); DeleteTree(pNode->pRightTree); delete pNode; pNode = nullptr; } void CHuffmanCode::PrintHuffmanCode() { std::queue<std::string> strQueue; PrintHuffmanCode(m_pRoot, strQueue); } void CHuffmanCode::PrintHuffmanCode(TreeNode* pNode, std::queue<std::string>& strQueue) { if (pNode->strName != "") { strQueue.push(pNode->strName); std::queue<std::string> swapQueue; while (!strQueue.empty()) { std::string str = strQueue.front(); std::cout << str.c_str(); strQueue.pop(); if (!strQueue.empty()) // 最后一个不push swapQueue.push(str); } swapQueue.swap(strQueue); std::cout << std::endl; } if (pNode->pLeftTree) { strQueue.push("0"); // 左子树的边是0 PrintHuffmanCode(pNode->pLeftTree, strQueue); strQueue.pop(); } if (pNode->pRightTree) { strQueue.push("1"); // 右子树的边是1 PrintHuffmanCode(pNode->pRightTree, strQueue); strQueue.pop(); } }
#include "HuffmanCode.h" int main() { CHuffmanCode huffman; huffman.InsertNode("a", 10); huffman.InsertNode("e", 15); huffman.InsertNode("i", 12); huffman.InsertNode("s", 3); huffman.InsertNode("t", 4); huffman.InsertNode("sp", 13); huffman.InsertNode("nl", 1); huffman.Generater(); huffman.PrintHuffmanCode(); std::cin.get(); return 0; }下图是哈夫曼的初始状态,及编码后的状态