通过哈夫曼树求解编码,输入字符串,输出编码,代码如下
#include<stdio.h>
#include<malloc.h>
#include<math.h>
#include<string.h>
typedef char TElemType;
typedef struct BiTNode {
TElemType data;
struct BiTNode* lchild, * rchild;
}BiTNode, * BiTree;//树节点
typedef struct HuffMan {
BiTree node;
int weight;
struct HuffMan* next;
}HuffMan, * HuffNode;//树链表
void InsertOrder(HuffNode T, HuffNode node);//顺序插入链表
HuffNode GetMinNode(HuffNode T);//取出最小权重的字符节点
void HuffManGenerate(HuffNode T);//生成哈夫曼树
void Getcode(char** CodeStorage, BiTree T, char* cd, int n);//计算编码
void Coding(char* str);
void InsertOrder(HuffNode T, HuffNode node) {
while (T->next)
{
if (node->weight < T->next->weight) {
node->next = T->next;
T->next = node;
return;
}
T = T->next;
}
T->next = node;
node->next = NULL;
}
HuffNode GetMinNode(HuffNode T) {
HuffNode re;
if (T->next) {
re = T->next;
}
T->next = re->next;
return re;
}
void HuffManGenerate(HuffNode T) {
while (T->next->next)
{
HuffNode nodeminone, nodemintwo;
nodeminone = GetMinNode(T);
nodemintwo = GetMinNode(T);
HuffNode node = (HuffNode)malloc(sizeof(HuffMan));
node->node = (BiTree)malloc(sizeof(BiTNode));
node->weight = nodeminone->weight + nodemintwo->weight;
node->node->lchild = nodeminone->node;
node->node->rchild = nodemintwo->node;
InsertOrder(T, node);
}
}
void Getcode(char** CodeStorage, BiTree T, char* cd, int n) {
if (!(T->lchild) && !(T->rchild)) {
cd[n] = '\0';
CodeStorage[T->data] = (char*)malloc(sizeof(char) * (strlen(cd) + 1));
strcpy(CodeStorage[T->data], cd);
}
if (T->lchild) {//进入左子树,编码为‘0’
cd[n] = '0';
Getcode(CodeStorage, T->lchild, cd, n + 1);
}
if (T->rchild) {//进入右子树,编码为‘1’
cd[n] = '1';
Getcode(CodeStorage, T->rchild, cd, n + 1);
}
}
void Coding(char* str) {
int data[256];
char* convertstr = str;
for (int i = 0; i < 256; i++)
{
data[i] = 0;
}
while (*str != '\0')
{
data[*str]++;
str++;
}
HuffMan T;
T.node = NULL;
T.next = NULL;
HuffNode p = &T;
for (int i = 0; i < 256; i++)//生成链表
{
if (data[i] > 0) {
HuffNode node = (HuffNode)malloc(sizeof(HuffMan));
node->node = (BiTree)malloc(sizeof(BiTNode));
node->node->lchild = NULL;
node->node->rchild = NULL;
node->weight = data[i];
node->node->data = i;
InsertOrder(&T, node);
}
}
HuffManGenerate(&T);//生成哈夫曼树
BiTree huffmantree = T.next->node;//得到哈夫曼树根节点
int length = strlen(convertstr);
char** CodeStorage = (char**)malloc(256 * sizeof(char*));
char* cd = (char*)malloc((length + 1) * sizeof(char));
Getcode(CodeStorage, huffmantree, cd, 0);//生成编码表
while (*convertstr != '\0')
{
printf("%s", CodeStorage[*convertstr]);//转换
convertstr++;
}
}
int main() {
Coding("aaaaaaabbbbbccddddfffqwerrtxzsgrsdvsg");
return 0;
}