构建哈夫曼树并计算叶子结点的哈夫曼编码,利用结构体指针数组构建。
#include<iostream>
#define length 6
using namespace std;
struct Tree{
int data;
Tree *left;
Tree *right;
};
//构造哈夫曼树
Tree *creatHT(int *arr){
Tree *pArr[length] = { NULL }; //结构体指针数组
Tree *p = NULL, *root = NULL;
for (int i = 0; i < length; i++){
pArr[i] = (Tree *)malloc(sizeof(Tree));
pArr[i]->left = NULL;
pArr[i]->right = NULL;
pArr[i]->data = arr[i];
}
for (int i = 0; i < length - 1; i++){ //每次将data最小和次小的结构体地址赋给数组的前两位
for (int m = i; m < length - 1; m++){ //每次循环后,下一次循环就往前移动一位(因为上一位被释放)
for (int j = m + 1; j < length; j++){
if (pArr[m]->data > pArr[j]->data){
Tree *temp = pArr[m];
pArr[m] = pArr[j];
pArr[j] = temp;
}
}
}
int k = i;
Tree *p = root;
root = (Tree *)malloc(sizeof(Tree));
root->left = pArr[k]; //合并每次排序下来最小的两位
root->right = pArr[k + 1];
root->data = pArr[k]->data + pArr[k + 1]->data;
pArr[k] = NULL; //每次合并后森林中的结点数减一,因此每次将数组的指针减一(指向空)并释放
free(pArr[k]); //每次合并的根节点存放在数组删除一个位置后的第一个位置,直到最后最终的根结点存放在数组的最后一个位置中
pArr[k + 1] = root;
}
return root;
}
int countWPL(Tree *root, int height = 0){
Tree *temp = root;
if (temp->left == NULL&&temp->right == NULL){
return temp->data*height;
}
else{
return countWPL(temp->left, height + 1) + countWPL(temp->right, height + 1);
}
}
void HuffmanCoding(Tree *root, int len){ //len为每个叶子的结点与根的路径长度
static int arr[10] = { 0 }; //相当于全局变量,只有第一次被初始化,后面递归会跳过初始化,原来值不变,叶子从左至右
if (root == NULL){
return;
}
if (root->left == NULL ){ //叶子结点,只需判断一个孩子是否为空,如果为空则两个孩子都为空
cout << "叶子权值为:" << root->data<<"\t"; //打印叶子结点的权值
for (int i = 0; i < len; i++){
cout << arr[i]; //根据叶子高度依次打印出哈夫曼编码
}
cout << endl;
return;
}
else{
arr[len] = 0; //由于是哈夫曼树,所以每个结点的度为0或2不可能为1(即有孩子一定是两个孩子)
HuffmanCoding(root->left, len +1);
arr[len] = 1; //往左走添个0,往右走添1
HuffmanCoding(root->right, len +1);
}
}
void traverse(const Tree *root){ //中序遍历哈夫曼树
const Tree *temp = root;
if (temp == NULL){
return;
}
if (temp->left != NULL){
traverse(temp->left);
}
cout << temp->data << endl;
if (temp->right != NULL){
traverse(temp->right);
}
}
int main(){
int arr[] = { 3, 9, 5, 12, 6, 15 };
creatHT(arr);
for (int i = 0; i < length; i++){
cout << arr[i] << endl;
}
cout << "----" << endl;
Tree *root = creatHT(arr);
traverse(root);
int w = countWPL(root);
cout << "WPL:" << w << endl;
HuffmanCoding(root, 0);
}