哈夫曼树的生成以及编码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include<iostream>
using namespace std;
typedef int ELEMTYPE;
typedef struct HuffmanTree
{
ELEMTYPE weight;
char value;
struct HuffmanTree* lchild;
struct HuffmanTree* rchild;
}HuffmanNode;
// 构建哈夫曼树
HuffmanNode* createHuffmanTree(int* a,char* b,int n)
{
int i, j;
HuffmanNode **temp, *hufmTree;
temp = (HuffmanNode **)malloc(n * sizeof(HuffmanNode));
for (i = 0; i < n; ++i) // 将数组a中的权值赋给结点中的weight
{
temp[i] = (HuffmanNode*)malloc(sizeof(HuffmanNode));
temp[i]->weight = a[i];
temp[i]->lchild = temp[i]->rchild = NULL;
temp[i]->value = b[i];
}
for (i = 0; i < n - 1; ++i) // n-1次合并
{
int small1 = -1, small2; // small1、small2分别作为最小和次小权值的下标
for (j = 0; j < n; ++j) // 先将最小的两个下标赋给small1、small2(注意:对应权值未必最小)
{
if (temp[j] != NULL && small1 == -1)
{
small1 = j;
continue;
}
else if (temp[j] != NULL)
{
small2 = j;
break;
}
}
if (small1 > small2)
{
int t = small1;
small1 = small2;
small2 = t;
}
for (j = small2; j < n; ++j) // 比较权值,挪动small1和small2使之分别成为最小和次小权值的下标
{
if (temp[j] != NULL)
{
if (temp[j]->weight < temp[small1]->weight)
{
small2 = small1;
small1 = j;
}
else if (temp[j]->weight < temp[small2]->weight)
{
small2 = j;
}
}
}
hufmTree = (HuffmanNode*)malloc(sizeof(HuffmanNode));
hufmTree->weight = temp[small1]->weight + temp[small2]->weight;
hufmTree->lchild = temp[small1];
hufmTree->rchild = temp[small2];
temp[small1] = hufmTree;
temp[small2] = NULL;
}
return hufmTree;
}
// 递归进行哈夫曼编码
void HuffmanCode(HuffmanNode* hufmTree, int depth,int*code) // depth是哈夫曼树的深度
{
if (hufmTree)
{
if (hufmTree->lchild == NULL && hufmTree->rchild == NULL)
{
printf("%c的哈夫曼编码为 ", hufmTree->value);
int i;
for (i = 0; i < depth; ++i)
{
printf("%d", code[i]);
}
printf("\n");
}
else
{
code[depth] = 0;
HuffmanCode(hufmTree->lchild, depth + 1,code);
code[depth] = 1;
HuffmanCode(hufmTree->rchild, depth + 1,code);
}
}
}
int main()
{
int i, n;
char string[100];
printf("请输入叶子结点的个数:\n");
scanf("%d", &n);
int* arr;
arr = (int*)malloc(n * sizeof(ELEMTYPE));
printf("请输入%d个叶子结点的权值及其各自代表的字符:\n", n);
for (i = 0; i < n; ++i)
{
printf("第%d个",i+1);
scanf("%d", &arr[i]);
scanf("%c", &string[i]);
}
HuffmanNode* hufmTree = NULL;
hufmTree = createHuffmanTree(arr,string,n);
int code[100];
printf("\n各叶子结点的哈夫曼编码为:\n");
HuffmanCode(hufmTree, 0,code);
return 0;
}
注意输入时权值与字符之间不加符号,否则会将空格当作字符,可以加一个getchar()来实现。
本文改编自
https://blog.youkuaiyun.com/F__shigang/article/details/65442550
删改了一些内容。