Huffman.h
#pragma once
#ifndef HUFFMAN_H
#define HUFFMAN_H
#include <iostream>
#include <vector>
#include <cstring>
using namespace std;
struct HuffmanNode
{
char data;
double weight;
int parent, lchild, rchild;
vector<char>code;
};
class HuffmanTree
{
vector<HuffmanNode>hufftree;
int n;
public:
HuffmanTree(vector<HuffmanNode>& leafs);
void SelectSmall(int& least, int& less, int n);
void GetCode();
void Printcode();
string Decode(vector<char> code);
};
HuffmanTree::HuffmanTree(vector<HuffmanNode>& leafs)
{
int least, less;
hufftree = leafs;
n = leafs.size();
hufftree.resize(2 * n - 1);
for (int i = n; i < 2 * n - 1; i++)
{
least = less = i;
SelectSmall(least, less, i);
hufftree[least].parent = i;
hufftree[less].parent = i;
hufftree[i].weight = hufftree[least].weight + hufftree[less].weight;
hufftree[i].lchild = least;
hufftree[i].rchild = less;
hufftree[i].parent = -1;
}
}
void HuffmanTree::SelectSmall(int& least, int& less, int n)
{
hufftree[n].weight = 100;
for (int i = 0; i < n; i++)
{
if (hufftree[i].parent == -1)
{
if (hufftree[i].weight < hufftree[least].weight)
{
less = least;
least = i;
}
else
if (hufftree[i].weight < hufftree[less].weight)
less = i;
}
}
}
void HuffmanTree::GetCode()
{
for (int i = 0; i < (hufftree.size() + 1) / 2; i++)
{
int parent = hufftree[i].parent;
int temp = i;
while (parent != -1)
{
if (hufftree[parent].lchild == temp)
hufftree[i].code.insert(hufftree[i].code.begin(), '0');
else
hufftree[i].code.insert(hufftree[i].code.begin(), '1');
temp = parent;
parent = hufftree[parent].parent;
}
}
}
void HuffmanTree::Printcode()
{
for (int i = 0; i < (hufftree.size() + 1) / 2; i++)
{
cout << "符号" << hufftree[i].data << "的哈夫曼编码为:";
for (int j = 0; j < hufftree[i].code.size(); j++)
cout << hufftree[i].code[j];
cout << endl;
}
cout << endl;
}
string HuffmanTree::Decode(vector<char> code)
{
string target = "";
int root = hufftree.size() - 1;
int p = root;
for (int i = 0; i < code.size(); i++)
{
if (code[i] == '0')
p = hufftree[p].lchild;
else
p = hufftree[p].rchild;
if (hufftree[p].lchild == -1 && hufftree[p].rchild == -1)
{
target = target + hufftree[p].data;
p = root;
}
}
return target;
}
#endif // !HUFFMAN_H
main.cpp
#include "Huffman.h"
using namespace std;
int main()
{
int n;
HuffmanNode node;
vector<HuffmanNode> leafs;
while (1)
{
cout << "请输入字母 enter 数字 enter,以@表示输入完成" << endl;
cout << "1. EXIT" << endl;
cin >> node.data;
if (node.data == '1')
exit(0);
while (node.data != '@')
{
cin >> node.weight;
node.parent = node.lchild = node.rchild = -1;
leafs.push_back(node);
cin >> node.data;
}
HuffmanTree tree(leafs);
tree.GetCode();
tree.Printcode();
while (1)
{
cout << "Please Input to Decode" << endl;
string str;
int i = 0;
cin >> str;
vector<char> code;
while (i < str.length())
{
code.push_back(str.at(i));
i++;
}
cout << tree.Decode(code) << endl;
code.clear();
int x;
cout << "2.Menu 3.New Decode" << endl;
cin >> x;
if (x == 2)
break;
}
leafs.clear();
}
return 0;
}