用C++实现Huffman编码树,代码如下
头文件:
//Huffman.h
#pragma once
#include<iostream>
#include <vector>
#include<algorithm>
#include<map>
#include<string>
using namespace std;
class Huffman
{
public:
Huffman();
virtual ~Huffman();
int buildHuffuman();
private:
//权重
int weight;
//左子节点
Huffman *left;
//右子节点
Huffman *right;
//待编码的字符
string str;
//设置叶子节点;
void leafHuffman(int setWeight, string str);
//设置一般节点;
void NodeHuffman(int setWeight, Huffman *setLeft, Huffman *setRight);
//判断是否是叶子节点;
bool isLeaf();
//自己的比较函数,用于重载sort函数,注意必须是静态的,不然的话须在类外声明;
static bool myHuffumanComepare(Huffman *node1, Huffman *node2);
// void getHuffmanSum(Huffman *root, int length, int &sum);
//得到叶子节点的编码;
void getNode(Huffman *root, string &prefix, map<string, string> &result);
};
cpp文件
#include "Huffman.h"
Huffman::Huffman()
{
this->left = nullptr;
this->right = nullptr;
this->weight = 0;
}
void Huffman::leafHuffman(int setWeight, string str)
{
this->str = str;
this->weight = setWeight;
this->left = nullptr;
this->right = nullptr;
}
void Huffman::NodeHuffman(int setWeight, Huffman * setLeft, Huffman * setRight)
{
this->weight = setWeight;
this->left = setLeft;
this->right = setRight;
}
Huffman::~Huffman()
{
}
bool Huffman::isLeaf()
{
return this->left == nullptr && this->right == nullptr;
}
bool Huffman::myHuffumanComepare(Huffman * node1, Huffman * node2)
{
return node1->weight > node2->weight;
}
void Huffman::getNode(Huffman * root, string & prefix, map<string, string>& result)
{
string m_prefix = prefix;
if (root->left == NULL)
return;
//处理左子树
prefix += "0";
//如果是叶子结点则输出,否则递归打印左子树
if (root->left->left == NULL)
{
result[root->left->str] = prefix;
cout << root->left->str << ": " << prefix << endl;
}
else
getNode(root->left, prefix, result);
//还原原来的路径,回溯
prefix = m_prefix;
//处理右子树
prefix += "1";
//如果是叶子结点,则输出, 否则递归打印右子树
if (root->right->right == NULL)
{
result[root->right->str] = prefix;
cout << root->right->str << ": " << prefix << endl;
}
else
getNode(root->right, prefix, result);
}
int Huffman::buildHuffuman()
{
int n;
while (cin >> n)
{
vector<Huffman*> weightArray;
while (n--)
{
int tempWeight;
string str;
cin >> str;
cin >> tempWeight;
Huffman *newNode=new Huffman;
newNode->leafHuffman(tempWeight, str);
weightArray.push_back(newNode);
}
sort(weightArray.begin(), weightArray.end(), myHuffumanComepare);
while ((int)weightArray.size() > 1)
{
Huffman *minNode1 = weightArray[weightArray.size() - 1];
Huffman *minNode2 = weightArray[weightArray.size() - 2];
int fatherWeight = minNode1->weight + minNode2->weight;
/*根据最小的两个权重节点,构造新节点*/
Huffman *fatherNode=new Huffman;
fatherNode->NodeHuffman(fatherWeight, minNode1, minNode2);
weightArray.pop_back();
weightArray.pop_back();
weightArray.push_back(fatherNode);
sort(weightArray.begin(), weightArray.end(), myHuffumanComepare);
}
//输出编码
string str;
map<string, string> result;
getNode(weightArray[0], str, result);
}
return 0;
}