哈夫曼编码(C++)以中序遍历顺序输出编码

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<vector>
using namespace std;
struct InputData* CreateHuffData(int size);
void OutputInputData(struct InputData*input_data,int size);
void CodingHuff(struct InputData*input_data,int size);
void PrintHuffCode(struct InputData*input_data,int size);

struct InputData{
	int weight;
	int value;
	int parent,lchild,rchild;
};

/*
进行编码*/
void CodingHuff(struct InputData*input_data,int size){
	int cur_size=size;
	//共有size-1次新树构造
	for(int i=0;i<size-1;i++){
		//找出权值最大的节点
		int max=input_data[0].weight;
		for(int j=0;j<cur_size;j++){
			if(input_data[j].weight>max){
				max=input_data[j].weight;
			}
		} 
		//在[0,cur_size)中找到两个权值最小且没有双亲的节点
		int min_1=max+1,min_2=max+1;//存储两个节点的权值
		int x_1=-1,x_2=-1;//记录两个最小权值节点的下标 
		for(int j=0;j<cur_size;j++){
			if(input_data[j].weight<min_1&&input_data[j].parent==-1){//j位置比两个权值都小 
				min_2=min_1;//min_2记录次小
				x_2=x_1;
				min_1=input_data[j].weight;
				x_1=j; 
			}else if(input_data[j].weight<min_2&&input_data[j].parent==-1){//j位置只比min_2要小
				min_2=input_data[j].weight;
				x_2=j;
			}
		}
		//找到了权值最小及次小的两个节点
		//更新新树的信息,新节点信息存储到下标为cur_size的位置
		input_data[cur_size].lchild=x_1;//最小节点
		input_data[cur_size].rchild=x_2;//次小节点
		input_data[cur_size].weight=min_1+min_2;//新节点权值
		input_data[x_1].parent=cur_size;
		input_data[x_2].parent=cur_size;
		cur_size+=1;			
	} 
}

/*
存储要编码信息*/
struct InputData* CreateHuffData(int size){
	//顺序存储 
	struct InputData*input_data=(struct InputData*)malloc(sizeof(struct InputData)*(size*2-1));
	//双亲,孩子全部置为-1
	for(int i=0;i<size*2-1;i++){
		input_data[i].parent=-1;
		input_data[i].lchild=-1;
		input_data[i].rchild=-1;
		input_data[i].weight=0;
		input_data[i].value=0;
	} 
	//信息输入 
	for(int i=0;i<size;i++){
		cin>>input_data[i].weight;
		input_data[i].value=input_data[i].weight;
	}
	//进行编码
	CodingHuff(input_data,size);
	return input_data;
};
 
/*
输出哈夫曼编码以中序遍历顺序输出*/
void PrintHuffCode(struct InputData*input_data,int root,vector<char>&huffcode){
	//每次输出到左孩子为-1,右孩子为-1为止
	//input_data[root]为根节点
	if(input_data[root].lchild!=-1&&input_data[root].rchild!=-1){//没遇到根节点
		huffcode.push_back('0'); 
		PrintHuffCode(input_data,input_data[root].lchild,huffcode);
		huffcode.push_back('1');
		PrintHuffCode(input_data,input_data[root].rchild,huffcode);
		huffcode.erase(huffcode.end()-1); 
	}else{//遇到根节点
		cout<<input_data[root].weight<<" ";
		for(int i=0;i<huffcode.size();i++){
			cout<<huffcode[i];
		}
		cout<<endl;
		huffcode.erase(huffcode.end()-1); 
	}
	return;
}




/*
输出InputData*/ 
void OutputInputData(struct InputData*input_data,int size){
//	for(int i=0;i<size*2-1;i++){
//		cout<<i<<": "<<input_data[i].weight<<" "<<input_data[i].parent<<" "<<input_data[i].lchild<<" "<<input_data[i].rchild<<" "<<input_data[i].value<<endl;
//	}
	vector<char>huffcode;
	PrintHuffCode(input_data,size*2-2,huffcode);
	huffcode.clear();	
} 
int main(int argc,char**argv){
	int size;
	cin>>size;
	struct InputData*huff_data=CreateHuffData(size);
	//验证输出
	OutputInputData(huff_data,size);	
	free(huff_data);
	return 0;
}

测试输入:5 2 7 4 5 19

预期输出:(对哈夫曼树按中序遍历输出对应叶子的哈夫曼编码)

7 00
5 010
2 0110
4 0111
19 1
测试输入数据说明:5代表共5个结点,后面的5个数字代表权值,不一定按顺序输入

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

高万禄

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值