哈夫曼树与哈夫曼编码(C++实现)

哈夫曼树与哈夫曼编码(C++实现)

  • 哈夫曼树的构造方法

1、**对给定的n个权值{W1,W2,W3,…,Wi,…,Wn}构成n棵二叉树的初始集合F={T1,T2,T3,…,Ti,…, Tn},其中每棵二叉树Ti中只有一个权值为Wi的根结点,它的左右子树均为空。
2、在F中选取两棵根结点权值最小的树作为新构造的二叉树的左右子树,新二叉树的根结点的权值为其左右子树的根结点的权值之和。
3、从F中删除这两棵树,并把这棵新的二叉树同样以升序排列加入到集合F中。
4、重复2)和3),直到集合F中只有一棵二叉树为止。

  • 哈夫曼编码步骤

一、对给定的n个权值{W1,W2,W3,…,Wi,…,Wn}构成n棵二叉树的初始集合F= {T1,T2,T3,…,Ti,…,Tn},其中每棵二叉树Ti中只有一个权值为Wi的根结点,它的左右子树均为空。(为方便在计算机上实现算 法,一般还要求以Ti的权值Wi的升序排列。)
二、在F中选取两棵根结点权值最小的树作为新构造的二叉树的左右子树,新二叉树的根结点的权值为其左右子树的根结点的权值之和。
三、从F中删除这两棵树,并把这棵新的二叉树同样以升序排列加入到集合F中。
四、重复二和三两步,直到集合F中只有一棵二叉树为止。

  • C++完整代码:
#include <iostream>
#include <string.h>
using namespace std ;
class HuffmanTreeNode{
	public:
		int weight ;
		int parent;
		int left;
		int right;
		void HuffmanTree(HuffmanTreeNode tree[] , int w[] ,int n);
		void select(HuffmanTreeNode tree[],int k,int &i1,int &i2);
		void HuffmanCode(HuffmanTreeNode tree[],string huffmanCode[],int n);
};
void HuffmanTreeNode::HuffmanTree(HuffmanTreeNode tree[] , int w[] ,int n){
	int i1 = 0;
	int i2 = 0; 
	//初始化结点为-1
	for(int i=0;i<2*n-1;i++){
		tree[i].parent = -1;
		tree[i].left = -1;
		tree[i].right = -1;
	} 
	//初始化前n个结点的权值
	for(int i=0;i<n;i++){
		tree[i].weight = w[i];
	} 
	//开始构建哈夫曼树
	for(int k = n ; k<2*n-1;k++){
		//首先找到parent==-1的最小和次小的结点

		select(tree,k,i1,i2);
		tree[k].weight = tree[i1].weight+tree[i2].weight;
		tree[i1].parent = k;
		tree[i2].parent = k;
		tree[k].left = i1;
		tree[k].right = i2; 
	} 
}
void HuffmanTreeNode::select(HuffmanTreeNode tree[],int k,int &i1,int &i2){
	i1 = 0;
	i2 = 0;
	int temp = 1000;
	for(int i = 0;i<k;i++){
		if(temp>tree[i].weight&&tree[i].parent==-1)
			temp = tree[i].weight;
			i1 = i ;
	}
	temp = 1000;
	for(int i = 0;i<k;i++){
		if(temp>tree[i].weight&&tree[i].parent==-1&&i!=i1){
			temp = tree[i].weight;
			i2 = i;
		}
	}
}

void HuffmanTreeNode::HuffmanCode(HuffmanTreeNode tree[] , string huffmanCode[],int n){
	//设置一个临时存储空间
	int cur; 
	int parent; 
	int start;
	//遍历哈夫曼树,生成哈夫曼编码
	for(int i=0;i<n;i++){
		cur = i ;//记录当前处理位置
		parent = tree[i].parent;//找到当前结点的父节点
		while(parent!=-1){//父节点不等于-1指的就是当前
			if(tree[parent].left==cur)
				huffmanCode[i] = '0' + huffmanCode[i];//当前为左子树则编码0
			else
				huffmanCode[i] = '1' + huffmanCode[i];
			
		//改变当前结点与父节点位置向上上搜索 
		cur = parent;
		parent = tree[parent].parent; 
		} 

	}
}
int main(){
	int count ;
	cout<<"请输入结点个数: ";
	cin>>count;
	cout<<"请输入"<<count<<"个权值:";
	int *w = new int[count];
	for(int i=0 ;i < count;i++){
		cin>>w[i];
	} 
	HuffmanTreeNode *tree = new HuffmanTreeNode[2*count-1] ;
	string huffmanCode[4];
	tree->HuffmanTree(tree,w,count);
	cout<<"weight\t\tparent\t\tleft\t\tright"<<endl;
	for(int i = 0;i<2*count-1;i++)
		cout<<tree[i].weight<<"\t\t"<<tree[i].parent<<"\t\t"<<tree[i].left<<"\t\t"<<tree[i].right<<endl;
	cout<<"哈夫曼编码为:"<<endl;
	tree->HuffmanCode(tree,huffmanCode,count);
	
	for(int i=0;i<count;i++)
		cout<<huffmanCode[i]<<" "; 
		cout<<s; 
	return 0;
} 
  • 运行结果:
    在这里插入图片描述
原创文章 30 获赞 15 访问量 3201

猜你喜欢

转载自blog.csdn.net/CSU_hjh/article/details/106160093