用模板写哈夫曼编码

来源:互联网 发布:单片机检测io口输入 编辑:程序博客网 时间:2024/04/29 23:41

    今天,我们一起使用模板来写一个哈夫曼编码类,具体如例1所示。

例1 对下面字符进行编码,使其总体长度最短。

字母={A,B,C,D,E},频率={15,7,6,6,5},字母和频率一一对应。

分析:解决这道题目的方法是使用哈夫曼编码,哈夫曼编码利用哈夫曼树构造前缀编码,使文本总体长度最短。

具体实现如下:

Huffman.hpp内容:

#ifndef _HUFFMAN_H_#define _HUFFMAN_H_#include <vector>#include <string>#include <iostream>using namespace std;template<typename T>struct Node{T m_Data;string m_strName;};template<typename T>struct TreeNode{Node<T> m_Info;TreeNode * m_pParent;TreeNode * m_pLeft;TreeNode * m_pRight;};template<typename T>class CHuffmanTree{public:CHuffmanTree();~CHuffmanTree();//初始化哈夫曼树bool InitForest(vector<Node<T> > & v);//构建哈夫曼树bool BuildHuffman();//销毁void Clear();//打印huffman编码void PrintEncode();private://销毁树void ClearTree(TreeNode<T> * pRoot);//中序遍历void InOrderTree(TreeNode<T> * pRoot);private:vector<TreeNode<T> *> m_vForest;TreeNode<T> * m_pRoot;};template<typename T>CHuffmanTree<T>::CHuffmanTree(){m_pRoot = NULL;}template<typename T>CHuffmanTree<T>::~CHuffmanTree(){vector<TreeNode<T> *>::iterator it;for (it = m_vForest.begin(); it != m_vForest.end(); it++){if (*it)ClearTree(*it);}m_vForest.clear();if (m_pRoot){ClearTree(m_pRoot);m_pRoot = NULL;}}template<typename T>bool CHuffmanTree<T>::InitForest(vector<Node<T> > & vWeights){TreeNode<T> * pNewNode = NULL;vector<Node<T> >::iterator it;for (it = vWeights.begin(); it != vWeights.end(); it++){pNewNode = new TreeNode<T>;if (!pNewNode){return false;}pNewNode->m_Info.m_Data = it->m_Data;pNewNode->m_Info.m_strName = it->m_strName;pNewNode->m_pParent = NULL;pNewNode->m_pLeft = NULL;pNewNode->m_pRight = NULL;m_vForest.push_back(pNewNode);}return true;}//构建哈夫曼树template<typename T>bool CHuffmanTree<T>::BuildHuffman(){TreeNode<T> * pMin = NULL;TreeNode<T> * pMin2 = NULL;TreeNode<T> * pNewNode = NULL;vector<TreeNode<T> *>::iterator it;vector<TreeNode<T> *>::iterator itMin;vector<TreeNode<T> *>::iterator itMin2;while (m_vForest.size() > 1){pNewNode = new TreeNode<T>;if (!pNewNode)return false;pMin = m_vForest[0];itMin = m_vForest.begin();for (it = m_vForest.begin(); it != m_vForest.end(); it++){if ((*it)->m_Info.m_Data < pMin->m_Info.m_Data){pMin = *it;itMin = it;}}m_vForest.erase(itMin);pMin2 = m_vForest[0];itMin2 = m_vForest.begin();for (it = m_vForest.begin(); it != m_vForest.end(); it++){if (((*it)->m_Info.m_Data < pMin2->m_Info.m_Data) && (*it != pMin)){pMin2 = *it;itMin2 = it;}}m_vForest.erase(itMin2);pNewNode->m_pLeft = pMin;pNewNode->m_pRight = pMin2;pNewNode->m_pParent = NULL;pNewNode->m_Info.m_Data = (pMin)->m_Info.m_Data + (pMin2)->m_Info.m_Data;pNewNode->m_Info.m_strName = (pMin)->m_Info.m_strName + (pMin2)->m_Info.m_strName;m_vForest.push_back(pNewNode);}m_pRoot = m_vForest[0];m_vForest.clear();return true;}template<typename T>void CHuffmanTree<T>::Clear(){vector<TreeNode<T> *>::iterator it;for (it = m_vForest.begin(); it != m_vForest.end(); it++){if (*it)ClearTree(*it);}m_vForest.clear();if (m_pRoot){ClearTree(m_pRoot);m_pRoot = NULL;}}template<typename T>void CHuffmanTree<T>::InOrderTree(TreeNode<T> * pRoot){vector<int>::iterator it;static vector<int> vPath;if (!pRoot)return;if (pRoot->m_pLeft){vPath.push_back(0);InOrderTree(pRoot->m_pLeft);}if ((pRoot->m_pLeft == NULL) && (pRoot->m_pRight == NULL)){cout << pRoot->m_Info.m_strName << "编码:";for (it = vPath.begin(); it != vPath.end(); it++){cout << *it;}cout << endl;}if (pRoot->m_pRight){vPath.push_back(1);InOrderTree(pRoot->m_pRight);}if (!vPath.empty())vPath.pop_back();return;}template<typename T>void CHuffmanTree<T>::PrintEncode(){if (m_pRoot)InOrderTree(m_pRoot);elsecout << "Huffman Tree is empty." << endl;}template<typename T>void CHuffmanTree<T>::ClearTree(TreeNode<T> * pRoot){if (!pRoot)return;if (pRoot->m_pLeft)ClearTree(pRoot->m_pLeft);if (pRoot->m_pRight)ClearTree(pRoot->m_pRight);delete pRoot;return;}#endif
main.cpp内容:

#include "Huffman.hpp"void main(){CHuffmanTree<int> HuffmanTree;vector<Node<int>> v;Node<int> tmp;tmp.m_strName = "A";tmp.m_Data = 15;v.push_back(tmp);tmp.m_strName = "B";tmp.m_Data = 7;v.push_back(tmp);tmp.m_strName = "C";tmp.m_Data = 6;v.push_back(tmp);tmp.m_strName = "D";tmp.m_Data = 6;v.push_back(tmp);tmp.m_strName = "E";tmp.m_Data = 5;v.push_back(tmp);HuffmanTree.InitForest(v);HuffmanTree.BuildHuffman();HuffmanTree.PrintEncode();HuffmanTree.Clear();system("pause");}
运行效果如图1所示:

图1  运行效果

    今天,我们共同使用模板完成了哈夫曼编码,希望大家回去多实践,熟练模板的使用。

0 0
原创粉丝点击