先po个源码,明天再写解析
此版本健壮性一般,所有方法均未封装,请谨慎参考
coding过程中遇到的问题:
https://ask.csdn.net/questions/7965692?spm=1001.2014.3001.5505
哈夫曼编码译码程序主要分为四个部分:建树,建表,编码,译码
与基于数组的哈夫曼数组相比,通过使用优先队列省去了建树过程中的挑选最小节点的操作,
#include <iostream>
#include <queue>
#include <string>
using namespace std;
struct HTree {
int weight; char letter; string code;
HTree* parent, * lchild, * rchild;
HTree() {
this->weight = 0;
this->letter = '\0';
this->code = "";
this->parent = NULL;
this->lchild = NULL;
this->rchild = NULL;
}
HTree(int weight) {
this->weight = weight;
this->letter = '\0';
this->code = "";
this->parent = NULL;
this->lchild = NULL;
this->rchild = NULL;
}
HTree(int weight, char letter) {
this->weight = weight;
this->letter = letter;
this->code = "";
this->parent = NULL;
this->lchild = NULL;
this->rchild = NULL;
}
};
//customization compare function
struct compare {
bool operator() (const HTree* h1, const HTree* h2) {
return h1->weight > h2->weight;
}
};
//little out first
//create a priority_queue
priority_queue <HTree*, vector<HTree*>, compare> HT;
vector<HTree*> htree;
HTree* top = NULL;
bool isleafnode(HTree* node) {
for (int u = 0; u < htree.size(); u++) {
if (htree[u] == node) {
return true;
}
}
return false;
}
//traserve the priority_queue
void traserve() {
while (!HT.empty()) {
cout << HT.top()->letter << "\t" << HT.top()->weight << "\t" << endl;
HT.pop();
}
}
//create a HuffmanTree
void CreateTree(int number) {
//input the nodes
HTree* ht = NULL;
for (int i = 1; i <= number; i++) {
cout << "type the " << i << " node's weight and letter please\n\n";
cout << "The letter of the node is: ";
char letter; cin >> letter;
cout << "The weight of the node is: ";
int weight = 0; cin >> weight;
cout << "\n\nThe letter is: " << letter << endl << "and the weight is: " << weight << endl;
ht = new HTree(weight, letter);
HT.push(ht);
htree.push_back(ht);
cout << "insert successful!\n\n";
}
cout << "The number of the vector's nodes is:" << htree.size() << endl;
cout << "\nall the nodes are inserted" << endl;
//create the HuffmanTree
HTree* hd = NULL;
HTree* hp = NULL;
while (HT.size() != 1) {
ht = HT.top(); HT.pop();
hd = HT.top(); HT.pop();
hp = new HTree(ht->weight + hd->weight);
ht->parent = hp; hd->parent = hp;
hp->lchild = ht; hp->rchild = hd;
HT.push(hp);
}
top = HT.top();
cout << HT.top()->weight << endl;
cout << "the creatation is done." << endl;
}
//create the codetable
void CreateTable() {
HTree* ht = NULL;
HTree* hp = NULL;
string code;
for (int u = 0; u < htree.size(); u++) {
code = "";
ht = htree[u]; hp = ht->parent;
while (hp != NULL) {
if (hp->lchild == ht) { code = "0" + code; }
else { code = "1" + code; }
ht = ht->parent; hp = hp->parent;
}
ht = htree[u]; ht->code = code;
cout << ht->letter << "\t" << ht->code << endl;
hp = NULL;
}
cout << "the table creatation process is done." << endl;
return;
}
//code
string Code(string str) {
HTree* ht = NULL;
string code = "";
cout << "Code function open successfully" << endl;
for (int u = 0; u < str.length(); u++) {
for (int i = 0; i < htree.size(); i++) {
ht = htree[i];
if (ht->letter == str[u]) {
code = code + ht->code;
break;
}
}
}
cout << code << endl;
cout << "code successfully!" << endl;
return code;
}
//decode
string Decode(string str) {
string decode = "";
HTree* ht = NULL;
cout << "decode open successful" << endl;
ht = top;
for (int u = 0; u < str.length(); u++) {
if (isleafnode(ht)) {
decode = decode + ht->letter;
ht = top;
}
if (str[u] == '0') {
ht = ht->lchild;
}
else {
ht = ht->rchild;
}
}
return decode;
}
//begin
void begin() {
cout << "welcome to the HuffmanTree create system!" << endl;
cout << "please operate under the guidance" << endl;
cout << "How many Nodes do you want to create? :";
int number; cin >> number;
cout << "OK,you wanna create " << number << " nodes" << endl;
CreateTree(number); CreateTable();
cout << "The string you wanna coding is:";
string str = ""; cin >> str;
cout << str << endl;
str = Code(str); cout << str << endl;
cout << "The string you wanna decoding is:" << endl;
cin >> str; str = Decode(str); cout << str << endl;
system("pause");
return;
}
int main() {
begin();
return 0;
}