哈夫曼树的构造与编码

#include <iostream>
#include <cstring>
using namespace std;
/*顺序结构*/
typedef struct {
	int weight;
	int parent, lch, rch;
} *HuffmanTree, HuffmanNode;
typedef char** HuffmanCode; 
/*构造哈夫曼树*/
void CreateHuffmanTree(HuffmanTree& HT, int n) {
	if (n <= 1) return;
	int m = n * 2 - 1;//n个结点的huffman树需要n-1个辅助结点
	HT = new HuffmanNode[m + 1];//从1开始 0不用
	/*选择两个最小的值,注意是从1到i-1,i是待设置的结点*/
	auto SelectTwoMin = [](HuffmanTree ht, int last, int & l, int & r){
		//注意要判断parent等于0才进行比较 
		int minIndex[] = { 0, 0 };//[0]小 [1]大
		ht[0].weight = 65536;//根结点用来放一个极大值,用来方便初始化第1和第2小值 
		for (int i = 1; i <= last; i++) {
			if (ht[i].parent == 0 && ht[i].weight < ht[minIndex[1]].weight) {
				if (ht[i].weight < ht[minIndex[0]].weight) {
					minIndex[0] = i;
				}
				else {
					minIndex[1] = i;
				}
			}
		}
		l = minIndex[0];
		r = minIndex[1];
		cout << "choose: " << l << " and " << r << endl;
		return;
	};
	int s1, s2;//声明两个最小值变量
	for (int i = 1; i <= m; i++) {
		//初始化1
		HT[i].lch = HT[i].rch = HT[i].parent = 0;
	}
	for (int i = 1; i <= n; i++) {
		//初始化2
		cin >> HT[i].weight;
	}
	for (int i = n + 1; i <= m; i++) {
		SelectTwoMin(HT, i - 1, s1, s2);//选择从1到i-1中权值最小的两个赋给s1和s2
		//为什么是到i-1呢,因为i是当前准备插入结点,i-1为最后一已经设置过的结点索引,注意这里不是n或者m
		HT[s1].parent = HT[s2].parent = i; 
		HT[i].lch = s1;
		HT[i].rch = s2;
		HT[i].weight = HT[s1].weight + HT[s2].weight;
	}
}
/*借助哈夫曼树构造哈夫曼编码*/
void CreateHuffmanCode(HuffmanTree HT, HuffmanCode & HC, int n){
	HC = new char*[n+1];//为n个字符分配 头指针,0不用所以是n+1
	char* cd = new char[n];//最多0到n-2个有效huffman编码,n-1用来存结束符 
	cd[n-1] =  '\0';
	int start;
	int child;
	int forward;
	for(int i = 1; i <= n; i++){
		start = n - 1;//为什么说从child=i=1开始是向前回溯呢,想一想表就知道了,初始输入的结点其index不变的,但是由于parent的变化最终会被挂成叶子结点 
		child = i;
		forward = HT[i].parent;
		while(forward != 0){
			start--;//每次开始往前走1 
			if(child == HT[forward].lch){
				cd[start] = '0';
			}else{
				cd[start] = '1';
			}
			child = forward;
			forward = HT[forward].parent;//末尾更新 
		}
		HC[i] = new char[n - start];
		strcpy(HC[i], &cd[start]);
		cout << HC[i] << endl;
	}
	delete cd;
}
int main() {
	HuffmanTree T;
	CreateHuffmanTree(T, 5);
	HuffmanCode HC;
	CreateHuffmanCode(T, HC, 5); 
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值