概述
程序要求
构建一个赫夫曼树编/译码器。根据提供的字符集和统计结果,按赫夫曼算法构造赫夫曼树,根据赫夫曼树得到每个赫夫曼编码并输出结果,能够将一个字符串转化为对应的赫夫曼编码串,能够将赫夫曼编码字符串译码。
数据结构题集(C语言版)清华大学出版社 p149 5.2
程序代码
#include <stdio.h>
#include <malloc.h>
#include <string.h>
typedef int Status ;
typedef char TElemType;
#define ERROR 0
#define OK 1
#define N 4
typedef struct {
unsigned int weight;
unsigned int parent,lchild,rchild;
}HTNode,*HuffmanTree; //动态分配数组存储赫夫曼树,Huffmantree是指针->HTNode
typedef char **HuffmanCode; //动态分配数组存储赫夫曼编码表
void select(HuffmanTree HT, int k, int &s1, int &s2)//select函数,从一组数中选出两个最小者
{
//假设s1对应的权值总是<=s2对应的权值
int tmp = 10000, tmpi = 0,i;
for(i = 1; i <= k; i++){
if(!HT[i].parent){//parent必须为0
if(tmp > HT[i].weight){
tmp = HT[i].weight;//tmp最后为最小的weight
tmpi = i;
}
}
}
s1 = tmpi;
tmp = 10000;
tmpi = 0;
for(i = 1; i <= k; i++){
if((!HT[i].parent) && i!=s1){//parent为0
if(tmp > HT[i].weight){
tmp = HT[i].weight;
tmpi = i;
}
}
}
s2 = tmpi;
}
//void HuffmanCoding(HuffmanTree &HT,HuffmanCode &HC,int *w,int n){
void HuffmanCoding(HuffmanTree &HT,HuffmanCode &HC,int *w,int n){
//w存放n个字符的权值(均>0),构造赫夫曼树HT,并求出n个字符的哈夫曼编码HC.
int m,i,s1,s2,start,c,f;
char *cd;
HuffmanTree p;
if(n<=1) return;
m=2*n-1;
HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode));
//0号单元未用
p=HT,p++;
for(i=1;i<=n;++i,++p,++w)
{
p->weight=*w;
p->parent=0;
p->lchild=0;
p->rchild=0;
}
for(;i<=m;++i,++p)
{
p->weight=0;
p->parent=0;
p->lchild=0;
p->rchild=0;
}
for(i=n+1;i<=m;++i)//建哈夫曼树
{
//在HT[1..i-1]选择parent为0且weight最小的两个结点,其序号分别为s1和s2.
select(HT,i-1,s1,s2);
HT[s1].parent=i;HT[s2].parent=i;
HT[i].lchild=s1;HT[i].rchild=s2;
HT[i].weight=HT[s1].weight+HT[s2].weight;
}
//-----从叶子到根逆向求每个字符的哈夫曼编码-----
HC=(HuffmanCode)malloc((n+1)*sizeof(char *)); //分配n个字符编码的头指针向量
//↑
//typedef char **HuffmanCode; //动态分配数组存储赫夫曼编码表
cd=(char *)malloc(n*sizeof(char));//分配求编码的工作空间
cd[n-1]='