#include<stdio.h> #include<stdlib.h> #define lnum 20 //默认权值集合大小 #define tnum 39 //树的结点个数 = 2*lnum-1 typedef struct { int data; //结点的值 int weight; //节点的权 int p,lc,rc; //双亲,左右孩子的指针 }htnode; typedef struct { htnode elem[tnum]; //数储存数组 int num,root; //num是外节点数,root是根 }hftree; void creatht(hftree &ht,int a[],int f[],int n,int maxweight){ int i,k,s1,s2,min1,min2; for(i=0;i<n;i++){ //所有外节点赋值 ht.elem[i].data=a[i]; ht.elem[i].weight=f[i]; } for(i=0;i<lnum;i++){ //所有指针指空 ht.elem[i].p=ht.elem[i].lc=ht.elem[i].rc=-1; } for(i=n;i<2*n-1;i++){ min2=maxweight; min1=min2; //maxweight表示最大的权 ,min1是最小值,min2是次小值 s1=s2=0; //s1是最小值点,s2是次小值点 for(k=0;k<i;k++) //构造哈夫曼树 if(ht.elem[i].weight<min1){ //未成为其他树的子树 min2=min1;s2=s1; //新的最小值 min1=ht.elem[i].weight; s1=k; //记忆新的最小 } else if(ht.elem[k].weight<min2){ min2=ht.elem[k].weight; s2=k; } ht.elem[s1].p = ht.elem[s2].p = i; ht.elem[i].lc = s1; ht.elem[i].rc = s2; ht.elem[i].weight = ht.elem[s1].weight+ht.elem[s2].weight; } ht.num = n; ht.root = 2*n-2; } int WeightLength(hftree &ht){ if(ht.elem.data==NULL) //空树返回0 return 0; else{ if(ht.elem[i].lc==NULL && ht.elem[i].rc==NULL){ //访问到叶子节点 return ptrTree->data * len; }else{ return WeightLength(ptrTree->left,len+1) + WeightLength(ptrTree->right,len+1); //向下递归计算 } } } main(){ hftree &ht; int a[],f[],n; a[]={1,4,7,2,5}; f[]={4,6,7,11,15}; n=5; int z = WeightLength(ht); creatht( ht, a[], f[], n,); }
从这以上,是一个不成功的开头。
以下,是可以运行的代码
不过,我没有输出一整棵HuffmanTree,只能一部分一部分的输出
#include <cstdio> #include <cstring> typedef struct { int weight; // 结点权值 int parent, lc, rc; // 双亲结点和左 右子节点 } HTNode, *HuffmanTree; void Select(HuffmanTree &HT, int n, int &s1, int &s2) { int minum; // 定义一个临时变量保存最小值? for(int i=1; i<=n; i++) // 以下是找到第一个最小值 { if(HT[i].parent == 0) { minum = i; break; } } for(int i=1; i<=n; i++) { if(HT[i].parent == 0) if(HT[i].weight < HT[minum].weight) minum = i; } s1 = minum; // 以下是找到第二个最小值,且与第一个不同 for(int i=1; i<=n; i++) { if(HT[i].parent == 0 && i != s1) { minum = i; break; } } for(int i=1; i<=n; i++) { if(HT[i].parent == 0 && i != s1) if(HT[i].weight < HT[minum].weight) minum = i; } s2 = minum; } void CreatHuff(HuffmanTree &HT, int *w, int n) { int m, s1, s2; m = n * 2 - 1; // 总结点的个数 HT = new HTNode[m + 1]; // 分配空间 for(int i=1; i<=n; i++) // 1 - n 存放叶子结点,初始化 { HT[i].weight = w[i]; HT[i].parent = 0; HT[i].lc = 0; HT[i].rc = 0; } for(int i=n+1; i<=m; i++) // 非叶子结点的初始化 { HT[i].weight = 0; HT[i].parent = 0; HT[i].lc = 0; HT[i].rc = 0; } printf("这个HuffmanTree是: \n"); for(int i = n+1; i<=m; i++) // 创建非叶子节点,建哈夫曼树 { // 在HT[1]~HT[i-1]的范围内选择两个parent为0且weight最小的两个结点,其序号分别赋值给 s1 s2 Select(HT, i-1, s1, s2); HT[s1].parent = i; // 删除这两个结点 HT[s2].parent = i; HT[i].lc = s1; // 生成新的树,左右子节点是 s1和s2 HT[i].rc = s2; HT[i].weight = HT[s1].weight + HT[s2].weight; // 新树的权 printf("%d (%d, %d)\n", HT[i].weight, HT[s1].weight, HT[s2].weight); } printf("\n"); } int main() { HuffmanTree HT; int *w, n, wei; printf("请输入节点数:\n"); scanf("%d", &n); w = new int[n+1]; printf("请输入节点的数据: \n", n); for(int i=1; i<=n; i++) { scanf("%d", &wei); w[i] = wei; } CreatHuff(HT, w, n); return 0; }