这几天重新把Huffman树重新捡了起来,发现了以前一个从来没有注意到的点:Huffman树的结构问题。
Huffman树并不是一个单边节点很多的一个二叉树,而是一个任意结构的二叉树,其构造结果和初始的权重值很有关系,这是以前从来没注意到的。
其次,在写代码中也注意到,寻找数组中以寻求两个索引较小的值的时候,需要注意索引大小和次序上的排列,最后,遍历Hufman树并且进行路径编码本质上就是一个二叉树遍历并且打标签的过程,所以并没有什么可说的,只需要进行逻辑关系判断即可。
#include<iostream>
#include<stack>
#include<vector>
#define NULLPOINT -1
#define MAX 1000
using namespace std;
using std::vector;
using std::stack;
class Hfm_node{
public:
int lchild=NULLPOINT;
int rchild=NULLPOINT;
int parent=NULLPOINT;
int data=NULLPOINT;
};
class HuffmanTree{
private:
vector<Hfm_node>Hfmlist;
public:
bool empty(vector<int>& v);
HuffmanTree(int membersize,vector<int>& par);
~HuffmanTree();
vector<int> chargement();
void construct_tree();
void en_and_de_code_simple();
void en_and_de_code_stack();
void recursion_HuffmanTree(int index);
};
HuffmanTree::HuffmanTree(int membersize,vector<int>& par){
//construct the size of vector,and give the parmas for the new Tree Vector
Hfmlist.resize(2*membersize-1);
for(size_t i=0;i<Hfmlist.size();i++){
Hfm_node node;
Hfmlist[i]=node;
}
for(size_t i=0;i<par.size();i++){
Hfmlist[i].data=par[i];
}
//construct the HuffmanTree
for(size_t i=par.size();i<Hfmlist.size();i++){
vector<int>index=chargement();
Hfmlist[index[0]].parent=i;
Hfmlist[index[1]].parent=i;
cout<<index[0];
cout<<index[1]<<endl;
Hfmlist[i].lchild=index[0];
Hfmlist[i].rchild=index[1];
Hfmlist[i].data=Hfmlist[index[0]].data+Hfmlist[index[1]].data;
}
/*
for(int i=0;i<Hfmlist.size();i++){
cout<<Hfmlist[i].data<<endl;
cout<<Hfmlist[i].lchild<<endl;
cout<<Hfmlist[i].rchild<<endl;
cout<<Hfmlist[i].parent<<endl<<endl;
}*/
}
bool HuffmanTree::empty(vector<int>& v){
bool flag=true;
for(int i=0;i<v.size();i++){
if(v[i]!=1)
flag=false;
}
return flag;
}
vector<int> HuffmanTree::chargement(){
//min1 always smaller than min2
vector<int>return_vec;
int min_index1=-1;
int min_index2=-1;
int min1=MAX;
int min2=MAX;
for(size_t i=0;i<Hfmlist.size();i++){
if(Hfmlist[i].parent==NULLPOINT&&Hfmlist[i].data!=NULLPOINT){
if(Hfmlist[i].data<=min1){
if(Hfmlist[i].data<min1){
min2=min1;
min_index2=min_index1;
min1=Hfmlist[i].data;
min_index1=i;
}
else{
min2=Hfmlist[i].data;
min_index2=i;
}
}
else{
if(Hfmlist[i].data<=min2){
min2=Hfmlist[i].data;
min_index2=i;
}
}
}
}
if(min1!=MAX&&min2!=MAX){
return_vec.push_back(min_index1);
return_vec.push_back(min_index2);
return return_vec;
}else{
return_vec.push_back(-1);
return return_vec;
}
}
HuffmanTree::~HuffmanTree(){
}
void HuffmanTree::en_and_de_code_simple(){
vector<int>charge(Hfmlist.size());
vector<int>code_path;
int index_start=Hfmlist.size()-1;
for(;!empty(charge);){
if(Hfmlist[index_start].lchild!=NULLPOINT&&charge[index_start]!=1&&charge[Hfmlist[index_start].lchild]!=1){
index_start=Hfmlist[index_start].lchild;
code_path.push_back(0);
}else{
if(Hfmlist[index_start].rchild!=NULLPOINT&&charge[Hfmlist[index_start].rchild]!=1){
charge[index_start]=1;
index_start=Hfmlist[index_start].rchild;
code_path.push_back(1);
}else{
cout<<"-----"<<index_start<<endl;
if(index_start<(Hfmlist.size()+1)/2){
cout<<Hfmlist[index_start].data<<" path:";
for(size_t k=0;k<code_path.size();k++)
cout<<code_path[k];
cout<<endl;
}
code_path.pop_back();
charge[index_start]=1;
index_start=Hfmlist[index_start].parent;
}
}
}
}
vector<int>path_recursion;
void HuffmanTree::recursion_HuffmanTree(int index){
if(index!=NULLPOINT&&Hfmlist[index].data!=NULLPOINT){
if(index==Hfmlist[Hfmlist[index].parent].lchild){
path_recursion.push_back(0);
}
else if(index==Hfmlist[Hfmlist[index].parent].rchild){
path_recursion.push_back(1);
}
recursion_HuffmanTree(Hfmlist[index].lchild);
recursion_HuffmanTree(Hfmlist[index].rchild);
if(Hfmlist[index].lchild==NULLPOINT&&Hfmlist[index].rchild==NULLPOINT){
cout<<Hfmlist[index].data<<"path :";
for(int i=0;i<path_recursion.size();i++)
cout<<path_recursion[i];
cout<<endl;
}
path_recursion.pop_back();
}
}
int main(int argc, char** argv) {
vector<int>par;
par.resize(5);
int k=1;
for(size_t i=0;i<5;i++){
par[i]=k++;
}
HuffmanTree hfm(5,par);
hfm.recursion_HuffmanTree(8);
return 0;
}