#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;
}
哈夫曼树的构造与编码
最新推荐文章于 2023-05-09 12:54:41 发布