哈夫曼树也称最优二叉树
1.从权值集合中选择权值最小的两个结点,构造一棵二叉树,根结点的权值为其左、右子树根结点权值之和。
2.删除这两个结点,将新生成的根结点加入到权值集合中。
3.重复以上步骤,直到权值集合中只剩下一个结点为止。
coding
//哈夫曼树
#include <stdio.h>
#include <stdlib.h>
typedef struct TreeNode {
int weight; //权值
int parent; //父结点
int lchild;
int rchild;
}TreeNode;
typedef struct HFTree {
TreeNode* data;
int length; //顺序表的长度
}HFTree;
HFTree* initTree(int* weight, int length) {
HFTree* T = (HFTree*)malloc(sizeof(HFTree));
T -> data = (TreeNode*)malloc(sizeof(TreeNode) * (2 * length - 1)); //给这个顺序表开辟2*n-1的长度,因为后续需要加入父结点
T -> length = length; //当前长度等于元素个数
for (int i = 0; i < length; i++) {
T -> data[i].weight = weight[i];
T -> data[i].parent = 0;
T -> data[i].lchild = -1;
T -> data[i].rchild = -1;
}
return T;
}
//挑选权值最小的两个结点
int* selectMin(HFTree* T) {
int min = 9999;
int secondMin = 9999;
int minIndex;
int secondIndex;
//挑选最小结点
for (int i = 0; i < T -> length; i++) {
if (T -> data[i].parent == 0) {
if (T -> data[i].weight < min) {
min = T -> data[i].weight;
minIndex = i;
}
}
}
//挑选第二小结点
for (int i = 0; i < T -> length; i++) {
if (T -> data[i].parent == 0 && i != minIndex) {
if (T -> data[i].weight < secondMin) {
secondMin = T -> data[i].weight;
secondIndex = i;
}
}
}
int* res = (int*)malloc(sizeof(int)* 2);
res[0] = minIndex;
res[1] = secondIndex;
return res;
}
void createHFTree(HFTree* T) {
int* res;
int min;
int secondMin;
int len = T -> length * 2 - 1;
for (int i = T -> length; i < len; i++) {
res = selectMin(T);
min = res[0];
secondMin = res[1];
T -> data[i].weight = T -> data[min].weight + T -> data[secondMin].weight;
T -> data[i].lchild = min;
T -> data[i].rchild = secondMin;
T -> data[i].parent = 0;
T -> data[min].parent = i;
T -> data[secondMin].parent = i;
T -> length ++;
}
}
void preOrder(HFTree* T, int index) {
if (index != -1) {
printf("%d ", T -> data[index].weight);
preOrder(T, T -> data[index].lchild);
preOrder(T, T -> data[index].rchild);
}
}
int main() {
int weight[4] = {1,2,3,4};
HFTree* T = initTree(weight, 4);
createHFTree(T);
preOrder(T, T -> length - 1);
printf("\n");
return 0;
}