源代码
#include <stdlib.h>
#include
#include
#include
struct HtNode{
double weight;
int parent,lchild,rchild;
};
struct HtTree{
HtNode* ht;
int root;
};
typedef struct HtTree* PHtTree;
//构造有n个节点的哈夫曼树
PHtTree Huffman (int n,int* w)
{
PHtTree pht;
HtNode* ht;
//用于记录权值最小的两棵树在数组中的位置
int i,j,p1,p2;
//min1,min2用于记录两个最小的权值
double min1,min2;
//输入合法
if(n<=0) return 0;
//动态分配Haffman树的空间
//int*n=(int*)malloc(sizeof(int)*n);
pht=(HtTree*)malloc(sizeof(HtTree));
pht->ht=(HtNode*)malloc(sizeof(HtNode)*(2*n-1));
//n个叶子共有2*n-1个节点
//初始化,设置ht数组的初始值
for(i=0;i<2*n-1;i++)
{
pht->ht[i].parent=0;
if(i { pht->ht[i].weight=w[i]; } else { pht->ht[i].weight=1000; } } //执行n-1次合并操作,即构造哈夫曼树的n-1个内部节点 for(i=0;i { p1=p2=0; //相关变量赋初值 min1=min2=1000;//相当于一个大数 for(j=0;j { if(pht->ht[j].parent==0) { if(pht->ht[j].weight { min1=pht->ht[j].weight; p1=j; } } } for(j=0;j { if(pht->ht[j].parent==0) { if((pht->ht[j].weight>min1)&&(pht->ht[j].weight<=min2)&&(j!=p1)) { min2=pht->ht[j].weight; p2=j; } } } pht->ht[p1].parent=n+i; pht->ht[p2].parent=n+i; pht->ht[n+i].weight=min1+min2; pht->ht[n+i].lchild=p1; pht->ht[n+i].rchild=p2; } //返回树 return pht; } //计算Huffman编码 void HuffmanCode(char** HC,int n,PHtTree pht) { int flag; //每个字符的编码最大长度不会超过n //这跟树的深度有关 char*c; //c=(char*)malloc(sizeof(char)*n); //分配n个字符指针数组空间 //第n-1单元存储编码串的结束符 int start; //逐个对n个字符求其哈夫曼编码 for(int i=0;i { flag=0; //start=n-1; //k,f是两个工作指针,f指向k的父亲 for(int k=i,f=pht->ht[i].parent;f!=0;k=f,f=pht->ht[k].parent) { flag++; //左边分配0,右边分配1 } //--------------- c=(char*)malloc(sizeof(char)*(flag)); c[flag]='\0'; for(int k=i,f=pht->ht[i].parent;f!=0;k=f,f=pht->ht[k].parent) { if(pht->ht[f].lchild==k) { c[--flag]='0'; } else { c[--flag]='1'; } } //为第i个字符编码分配空间 //因为路径有长有短 HC[i]=(char*)malloc(sizeof(char)); strcpy(HC[i],c); } } int main() { //输入 int n; int m; HtNode* ht; int* weight; char** HC; PHtTree pht; printf("请输入需要哈夫曼编码的节点数目\n"); scanf("%d",&n); //分配内存空间 ht=(HtNode*)malloc(sizeof(HtNode)*n); weight=(int*)malloc(sizeof(int)*n); HC=(char**) malloc(sizeof(char*)*n); printf("请输入各节点的值\n"); for(int i=0;i { printf("第%d个节点的权值:\n",i); scanf("%d",&m); weight[i]=m; printf("\n"); } //构造具有n个节点的Haffman树 pht=Huffman(n,weight); HuffmanCode(HC,n,pht); //输出编码 for(int i=0;i { int j=0; printf("第%d个字符的编码,它的权值为是%d:\n",i,weight[i]); { printf("%s\n",HC[i]); //j++; } } return 0; }