今天寫了寫哈夫曼樹..
首先是頭文件heads.h
#pragma once
#include<iostream>
#include<vector>
#include<string>
#include<deque>
#include<stack>
#include<unordered_map>
#include<algorithm>
using namespace std;
然後還是頭文件
#pragma once
#include"heads.h"
namespace haffuman
{
class haffumant
{
public:
struct tnode
{
char data;
int weight;
tnode *parent;
tnode *lchild;
tnode *rchild;
};
public:
/*這裏寫了一個自己的排序的類,用來生成類對象*/
class mysort
{
public:
bool operator ()(tnode * a, tnode *b)
{
return a->weight < b->weight;
}
};
haffumant(int num, vector<tnode*> &datas) :sum(num), nodes(datas)
{
sort(nodes.begin(), nodes.end(), mysort());//按權值排序,當然可以用最小堆,這裏我不想用堆
}
haffumant() :sum(0)
{
}
/*利用中序遍歷來完成編碼的工作,將編碼結果保存在了hashmap中*/
void huffmancode()
{
stack<tnode *> tm_sta;
tnode * psear = root;
vector<int> tm_code;
tm_sta.push(root);
while (!tm_sta.empty())
{
while (psear->lchild != NULL)
{
tm_sta.push(psear->lchild);
psear = psear->lchild;
tm_code.push_back(0);
}
//psear = tm_sta.top();
tm_sta.pop();
code[psear->data] = tm_code;
if (tm_sta.empty())
{
break;
}
psear = tm_sta.top();
tm_sta.pop();
tm_code.pop_back();
if (psear->rchild != nullptr)
{
tm_sta.push(psear->rchild);
psear = psear->rchild;
tm_code.push_back(1);
}
else
{
return;
}
}
}
void huffmancode1()
{
/*還有一種簡單的方法,由於保存了各個葉節點,那麼可以從下向上遍歷...通過parent指針.
但是這種方法有種缺陷就是得到的編碼是顛倒的,當然可以通過遞歸來解決,或者棧..也可以通過
其他手段,能解決逆置的問題就可以
*/
}
void settree()
{
while (nodes.size() > 1)
{
root = buynode(nodes[0]->weight + nodes[1]->weight, NULL, nodes[1], nodes[0]);
nodes[0]->parent = root;
nodes[1]->parent = root;
nodes.erase(nodes.begin());
nodes.erase(nodes.begin());
nodes.push_back(root);
sort(nodes.begin(), nodes.end(), mysort());
}
}
void show()
{
show(root);
for (auto it : code)
{
int i = 0;
cout << it.first;
while (i < it.second.size())
{
cout << it.second[i++];
}
cout << "\n";
}
}
~haffumant()
{
clear(root);
}
private:
void clear(tnode * node)
{
if (node != nullptr)
{
clear(node->lchild);
clear(node->rchild);
delete node;
}
}
void show(tnode *root1)
{
if (root1 == NULL) return;
cout << root1->data;
show(root1->lchild);
show(root1->rchild);
}
tnode * buynode(int weight, tnode *par, tnode*rchld, tnode *lchild)
{
return new tnode{ '@',weight,par,lchild,rchld };
}
vector<tnode*> nodes;
tnode * root = NULL;
unordered_map<char, vector<int>> code;
int sum;
};
};
最後就是主函數用來驗證下,寫的如何..
#include"haffumantree.h"
using namespace haffuman;
int main()
{
vector<haffumant::tnode *> arr =
{
new haffumant::tnode{'a',5,NULL,NULL,NULL},
new haffumant::tnode{'c',2,NULL},
new haffumant::tnode{'b',7,NULL},
new haffumant::tnode{ 'd',13,NULL }
};
haffumant tree(arr.size(),arr);
tree.settree();
tree.huffmancode();
tree.show();
}
哈夫曼樹,是最優二叉樹,也就是帶權路徑長度值最小的二叉樹,權值越大越靠近根,哈夫曼編碼也可以用於進行壓縮…