1 #include<stdio.h>
2 #include<stdlib.h>
3 #define leafNumber 20
4 #define totalNumber 39
5 #define maxValue 32767
6 typedef struct{
7 char data;
8 int weight;
9 int parent,lchild,rchild;
10 }HTNode;
11 typedef struct{
12 HTNode elem[totalNumber];
13 int num,root; //root为哈夫曼树树根的指针,num是当前树中的总结点数
14 }HFTree;
15
16 void createHFTree(HFTree &HT,char value[],int fr[],int n){
17 int i,k,s1,s2;
18 int min1,min2;
19 for(i = 0;i<n;i++){
20 HT.elem[i].data = value[i];
21 HT.elem[i].weight = fr[i]; //赋权值
22 }
23 for(i = 0;i<leafNumber;i++){
24 HT.elem[i].parent = HT.elem[i].lchild = HT.elem[i].rchild = -1;
25 }
26 for(i = n;i<2*n-1;i++){
27 min1 = min2 = maxValue;
28 s1 = s2 = 0;
29 for(k = 0;k<i;k++)
30 if(HT.elem[k].parent == -1)
31 if(HT.elem[k].weight < min1)
32 {
33 min2 = min1;
34 s2 = s1;
35 min1 = HT.elem[k].weight;
36 s1 = k;
37 }
38 else if(HT.elem[k].weight<min2)
39 {
40 min2 = HT.elem[k].weight;
41 s2 = k;
42 }
43 HT.elem[s1].parent = HT.elem[s2].parent = i;
44 HT.elem[i].lchild = s1;
45 HT.elem[i].rchild = s2;
46 HT.elem[i].weight = HT.elem[s1].weight+HT.elem[s2].weight;
47 }
48 HT.num = n;
49 HT.root = 2*n-2;//最后一个元素是树根
50 }
51
52 int MyCalWPL(HFTree &HT,int i,int length,int &WPL){
53 int lWPL, rWPL;
54 if(HT.elem[i].lchild!=-1)
55 MyCalWPL(HT,HT.elem[i].lchild,length++,WPL);
56 else{
57 lWPL = length*HT.elem[i].weight;
58 return lWPL;
59 }
60 if(HT.elem[i].rchild!=-1)
61 MyCalWPL(HT,HT.elem[i].rchild,length++,WPL);
62 else
63 rWPL = length*HT.elem[i].weight;
64 return WPL = lWPL+rWPL+WPL;
65 }
66
67 int CalWPL(HFTree &HT,int i){
68 int lc,rc;
69 if(HT.elem[i].lchild>-1&&HT.elem[i].rchild>-1)
70 {
71 lc = CalWPL(HT,HT.elem[i].lchild);
72 rc = CalWPL(HT,HT.elem[i].rchild);
73 return HT.elem[i].weight+lc+rc;
74 }
75 else
76 return 0;
77 }
78
79 //广义表输出
80 void MyPrint(HFTree &HT,int i){
81 if(i>-1){
82 printf("%d",HT.elem[i].weight);
83 if(HT.elem[i].lchild>-1||HT.elem[i].rchild>-1){
84 printf("(");
85 MyPrint(HT,HT.elem[i].lchild);
86 printf(",");
87 MyPrint(HT,HT.elem[i].rchild);
88 printf(")");
89 }
90 }
91 }
92 //凹入表输出
93 void Print(HFTree &HT,int i,int k){
94 for(int j = 0;j<k;j++)
95 printf(" ");
96 printf("%d\n",HT.elem[i].weight);
97 if(HT.elem[i].lchild>-1)
98 Print(HT,HT.elem[i].lchild,k+4);
99 if(HT.elem[i].rchild>-1)
100 Print(HT,HT.elem[i].rchild,k+4);
101 }
102
103 int main(){
104 HFTree HT;
105 int length = 0,WPL = 0;
106 char value[] = {'A','B','C','D','E','F','G','H','I'};
107 int fr[] = {7,5,2,4,6};
108 createHFTree(HT,value,fr,5);
109 MyPrint(HT,HT.root);
110 printf("哈夫曼树的带权路径长度为:%d",CalWPL(HT,HT.root));
111 }