[实例]利用霍夫曼树获得霍夫曼编码并进行加密和解密

[align=center][img]https://api5.yunpan.360.cn/intf.php?method=Share.getPublicThumbByNid&qid=108635719&nid=14671735779402431&size=800_600&devtype=web&v=1.0.1&rtick=14671736103546&share_qid=108635719&sign=954b8f2ce796ba5572c7812499ac61f8&[/img] [/align]

[align=center][img]https://api5.yunpan.360.cn/intf.php?method=Share.getPublicThumbByNid&qid=108635719&nid=14671798239497213&size=800_600&devtype=web&v=1.0.1&rtick=14671798308044&share_qid=108635719&sign=dc6e95501416aeaa4c6e13b685de7e89&[/img][/align]

奋战一个晚上把基本功能实现了

//HuffmanTree.h

#ifndef HUFFMAN_TREE_H
#define HUFFMAN_TREE_H

#include <Windows.h>
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;

namespace HuffmanTreeSpace
{
struct HuffmanTreeNode
{
int nData;
string strData;
string strHuffmanCodeing;
HuffmanTreeNode* pRoot;
HuffmanTreeNode* pLeftChild;
HuffmanTreeNode* pRightChild;

HuffmanTreeNode()
{
nData = 0;

pRoot = NULL;
pLeftChild = NULL;
pRightChild = NULL;
}

// bool operator < (const HuffmanTreeNode& rhs) const // 升序排序时必须写的函数
// {
// return nData < rhs.nData;
// }
// bool operator > (const HuffmanTreeNode& rhs) const // 降序排序时必须写的函数
// {
// return nData > rhs.nData;
// }
};

typedef struct tag_SingleCode
{
int nData;
string strData;
string strCoding;
}SingleCode, *PSingleCode;

typedef vector<HuffmanTreeNode*> TreeNodeArray;
typedef vector<SingleCode> HuffmanCodingTable;

enum EM_HUFFMAN_ORDER
{
EM_HUFFMAN_DLR = 0,
EM_HUFFMAN_LDR = 1,
EM_HUFFMAN_LRD = 2
};

class HuffmanTree
{
public:
HuffmanTree();

void AddRawDataToNode(string strData);
void AddNode(int nData, string strData);
void MySort();

void Gnenerate();
void PrintTreeNode();

void PrintNode(EM_HUFFMAN_ORDER emType, const HuffmanTreeNode* pNode);
void GetHuffmanNode(const HuffmanTreeNode* pNode, int nData, string strData);
string PrintHuffmanCode(int nData, string strData);

HuffmanTreeNode* GetRoot()
{
return m_pRootNode;
}

void GenerateCodingTable();
string HuffmanEncoding(const string& strRaw);
string HuffmanDecoding(const string& strEncoded);

public:
string m_strTemp;
const HuffmanTreeNode* m_pTemp;

HuffmanCodingTable m_CodingTable;

private:
TreeNodeArray m_TreeNodes; //本示例没有考虑内存的释放,后续可以改进
HuffmanTreeNode* m_pRootNode;
string strHuffCode;
};

//
void HuffmanTree_Test1();
void HuffmanTree_Test2();
void HuffmanTree_Test3();
}

#endif



#include "HuffmanTree.h"

namespace HuffmanTreeSpace
{
HuffmanTree::HuffmanTree()
:m_pRootNode(NULL)
{
}

bool less_second(char char1, char char2)
{
return char1 < char2;
}

void HuffmanTree::AddRawDataToNode(string strData)
{
m_CodingTable.clear();

//统计字符出现的频率
string strTemp = strData;
sort(strTemp.begin(), strTemp.end()/*, less_second*/);

while (strTemp.size() > 0)
{
string strData;
const char* ptr = strTemp.c_str();
int nSize = count(strTemp.begin(), strTemp.end(), *ptr);
strData = *ptr;

AddNode(nSize, strData);

strTemp = strTemp.substr(nSize, strTemp.size()-nSize);
}
}

void HuffmanTree::AddNode(int nData, string strData)
{
HuffmanTreeNode* pNode = new HuffmanTreeNode();
pNode->nData = nData;
pNode->strData = strData;
m_TreeNodes.push_back(pNode);

SingleCode singleCode;
singleCode.nData = nData;
singleCode.strData = strData;
m_CodingTable.push_back(singleCode);
}

//升序排序
bool lessmark(const HuffmanTreeNode* treeNode1, const HuffmanTreeNode* treeNode2)
{
return (treeNode1->nData < treeNode2->nData);
}

//降序排序
bool greatermark(const HuffmanTreeNode* treeNode1, const HuffmanTreeNode* treeNode2)
{
return treeNode1->nData > treeNode2->nData;
}


void HuffmanTree::MySort()
{
sort(m_TreeNodes.begin(), m_TreeNodes.end(), lessmark);
}

void HuffmanTree::Gnenerate()
{
MySort();

while (m_TreeNodes.size() > 1)
{
//PrintTreeNode();

int nsize = m_TreeNodes.size();
TreeNodeArray::iterator iter = m_TreeNodes.begin();
TreeNodeArray::iterator iter2 = m_TreeNodes.begin();
++iter2;

HuffmanTreeNode* pNode = new HuffmanTreeNode();

pNode->nData = (*iter)->nData + (*iter2)->nData;
pNode->strData = (*iter)->strData + (*iter2)->strData;
(*iter)->strHuffmanCodeing = "0";
(*iter2)->strHuffmanCodeing = "1";

(*iter)->pRoot = pNode;
(*iter2)->pRoot = pNode;

pNode->pLeftChild = *iter;
pNode->pRightChild = *iter2;

m_TreeNodes.erase(iter2);
m_TreeNodes.erase(iter);

m_TreeNodes.push_back(pNode);

MySort();
}

m_pRootNode = *m_TreeNodes.begin();

GenerateCodingTable();
}

void HuffmanTree::PrintTreeNode()
{
TreeNodeArray::iterator iter = m_TreeNodes.begin();
TreeNodeArray::iterator end = m_TreeNodes.end();

for(; iter != end; ++iter)
{
cout << "Val = " << (*iter)->nData << "str = " << (*iter)->strData << " address = " <<(*iter)->pLeftChild << ", " <<(*iter)->pRightChild << endl;
}
}

void HuffmanTree::PrintNode(EM_HUFFMAN_ORDER emType, const HuffmanTreeNode* pNode)
{
if (pNode != NULL)
{
if (EM_HUFFMAN_DLR == emType)
{
cout << " " << pNode->nData << "(" << pNode->strData << "," << pNode->strHuffmanCodeing << ")";
}

//Get Left Leaf
if (pNode->pLeftChild != NULL)
{
PrintNode(emType, pNode->pLeftChild);
}

if (EM_HUFFMAN_LDR == emType)
{
cout << " " << pNode->nData << "(" << pNode->strData << "," << pNode->strHuffmanCodeing << ")";
}

//Get Right Leaf
if (pNode->pRightChild != NULL)
{
PrintNode(emType, pNode->pRightChild);
}

if (EM_HUFFMAN_LRD == emType)
{
cout << " " << pNode->nData << "(" << pNode->strData << "," << pNode->strHuffmanCodeing << ")";
}
}
}

void HuffmanTree::GetHuffmanNode(const HuffmanTreeNode* pNode, int nData, string strData)
{
if (pNode != NULL)
{
if (pNode->nData==nData
&& pNode->strData==strData)
{
if (NULL == m_pTemp)
{
m_pTemp = pNode;
}
return;
}
else
{
m_strTemp = m_strTemp.substr(0, m_strTemp.length()-1);
}

//Get Left Leaf
if (pNode->pLeftChild != NULL)
{
if (pNode->pLeftChild->nData==nData
&& pNode->pLeftChild->strData==strData)
{
if (NULL == m_pTemp)
{
m_pTemp = pNode->pLeftChild;
}

m_strTemp = m_strTemp.substr(0, m_strTemp.length()-1);
return;
}
else
{
GetHuffmanNode(pNode->pLeftChild, nData, strData);
//cout << "0";
//m_strTemp = "0" + m_strTemp;
}
}
else
{
m_strTemp = m_strTemp.substr(0, m_strTemp.length()-1);
}

//Get Right Leaf
if (pNode->pRightChild != NULL)
{
if (pNode->pRightChild->nData==nData
&& pNode->pRightChild->strData==strData)
{
if (NULL == m_pTemp)
{
m_pTemp = pNode->pRightChild;
}

m_strTemp = m_strTemp.substr(0, m_strTemp.length()-1);
return;
}
else
{
GetHuffmanNode(pNode->pRightChild, nData, strData);
//cout << "1";
//m_strTemp = "1" + m_strTemp;
}
}
else
{
m_strTemp = m_strTemp.substr(0, m_strTemp.length()-1);
}
}
}

string HuffmanTree::PrintHuffmanCode(int nData, string strData)
{
string strHuffmanCode;

m_strTemp = "";
m_pTemp = NULL;

//cout << "---------------------------------------------------" << endl;
GetHuffmanNode(m_pRootNode, nData, strData);
//cout << "Temp=" << m_strTemp << "\n" << strData << "(" << nData << ") = ";

const HuffmanTreeNode* ptr = m_pTemp;
while (ptr != NULL)
{
strHuffmanCode = ptr->strHuffmanCodeing + strHuffmanCode;
//cout << " " << ptr->nData << "(" << ptr->strHuffmanCodeing << ")";
ptr = ptr->pRoot;
}
cout << strData << " = " << strHuffmanCode << endl;
//cout << "---------------------------------------------------" << endl;

return strHuffmanCode;
}

void HuffmanTree::GenerateCodingTable()
{
HuffmanCodingTable::iterator iter= m_CodingTable.begin();
HuffmanCodingTable::iterator end= m_CodingTable.end();

for ( ; iter != end; ++iter)
{
iter->strCoding = PrintHuffmanCode(iter->nData, iter->strData);
}
}

string& replace_all_distinct(string& str,const string& old_value,const string& new_value)
{
for(string::size_type pos(0); pos!=string::npos; pos+=new_value.length())
{
if ((pos=str.find(old_value,pos))!=string::npos)
{
str.replace(pos,old_value.length(),new_value);
}
else
{
break;
}
}

return str;
}

string HuffmanTree::HuffmanEncoding(const string& strRaw)
{
HuffmanCodingTable::const_iterator iter= m_CodingTable.begin();
HuffmanCodingTable::const_iterator end= m_CodingTable.end();
string strTemp = strRaw;

for ( ; iter != end; ++iter)
{
replace_all_distinct(strTemp, iter->strData, iter->strCoding);
}

return strTemp;
}

string HuffmanTree::HuffmanDecoding(const string& strEncoded)
{
string strTemp = strEncoded;
string strNew;

while (strTemp.length() > 0)
{
HuffmanCodingTable::const_iterator iter= m_CodingTable.begin();
HuffmanCodingTable::const_iterator end= m_CodingTable.end();
for ( ; iter != end; ++iter)
{
//replace_all_distinct(strTemp, iter->strData, iter->strCoding);
size_t nPos = strTemp.find(iter->strCoding);

if (0 == nPos)
{
//cout << "\n" << strTemp << " ==> \n";
strTemp = strTemp.substr(iter->strCoding.length(), strTemp.size()-iter->strCoding.length());
//cout << strTemp << endl;
strNew += iter->strData;
//cout << "\n" << strNew << endl;
break;
}
}
}

return strNew;
}

//
void HuffmanTree_Test1()
{
string strRawData = "abdacdcdBAdCCCCdCDdDD";
string strEncoding;
string strDecoding;
HuffmanTree huffmanTree;

cout << "------------------HuffmanTree_Test1-----------------------\n";
cout << "Pliantext = " << strRawData << endl;

huffmanTree.AddNode(2, "a");
huffmanTree.AddNode(1, "b");
huffmanTree.AddNode(2, "c");
huffmanTree.AddNode(6, "d");
huffmanTree.AddNode(1, "A");
huffmanTree.AddNode(1, "B");
huffmanTree.AddNode(5, "C");
huffmanTree.AddNode(3, "D");

huffmanTree.Gnenerate();

strEncoding = huffmanTree.HuffmanEncoding(strRawData);
cout << "Encoding = " << strEncoding << endl;

strDecoding = huffmanTree.HuffmanDecoding(strEncoding); //
cout << "Decoding = " << strDecoding << endl;
cout << "----------------------------------------------------------\n";

}

void HuffmanTree_Test2()
{
string strRawData = "abdacdcdBAdCCCCdCDdDD";
string strEncoding;
string strDecoding;
HuffmanTree huffmanTree;

cout << "------------------HuffmanTree_Test2-----------------------\n";
cout << "Pliantext = " << strRawData << endl;

huffmanTree.AddRawDataToNode(strRawData);
huffmanTree.Gnenerate();

strEncoding = huffmanTree.HuffmanEncoding(strRawData);
cout << "Encoding = " << strEncoding << endl;

strDecoding = huffmanTree.HuffmanDecoding(strEncoding); //
cout << "Decoding = " << strDecoding << endl;
cout << "----------------------------------------------------------\n";
}

void HuffmanTree_Test3()
{
string strRawData = "abdacdcdBAdCCCCdCDdDD";
string strEncoding;
string strDecoding;
HuffmanTree huffmanTree;

cout << "------------------HuffmanTree_Test3-----------------------\n";
cout << "Pliantext = " << strRawData << endl;

huffmanTree.AddNode(1, "A");
huffmanTree.AddNode(1, "B");
huffmanTree.AddNode(5, "C");
huffmanTree.AddNode(3, "D");
huffmanTree.AddNode(2, "a");
huffmanTree.AddNode(1, "b");
huffmanTree.AddNode(2, "c");
huffmanTree.AddNode(6, "d");

huffmanTree.Gnenerate();

strEncoding = huffmanTree.HuffmanEncoding(strRawData);
cout << "Encoding = " << strEncoding << endl;

strDecoding = huffmanTree.HuffmanDecoding(strEncoding); //
cout << "Decoding = " << strDecoding << endl;
cout << "----------------------------------------------------------\n";
}
}


[align=center][img]https://api5.yunpan.360.cn/intf.php?method=Share.getPublicThumbByNid&qid=108635719&nid=14671735789406227&size=800_600&devtype=web&v=1.0.1&rtick=14671736108716&share_qid=108635719&sign=f9b614324624a36f7c013bf10acad51b&[/img][/align]
[align=center][img]https://api5.yunpan.360.cn/intf.php?method=Share.getPublicThumbByNid&qid=108635719&nid=14671735789410839&size=800_600&devtype=web&v=1.0.1&rtick=14671736109530&share_qid=108635719&sign=3faaeea3a846bc8220039b195cafa811&[/img][/align]
[align=center][img]https://api5.yunpan.360.cn/intf.php?method=Share.getPublicThumbByNid&qid=108635719&nid=14671735799417092&size=800_600&devtype=web&v=1.0.1&rtick=14671736108316&share_qid=108635719&sign=4d07d228dcad16ae37be0eefb456c274&[/img][/align]
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值