Huffman树

    这几天重新把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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值