HuffmanTree
huffmanTree.h
1 #include <STDIO.H> 2 #include <STDLIB.H> 3 #include <MALLOC.H> 4 #include <STRING.H> 5 6 #define MAXSIZE 10 7 8 typedef struct 9 { 10 unsigned int weight; 11 unsigned int left,right,parent; 12 }HTNode,* HuffmanTree; 13 14 typedef char * * HuffmanCode; 15 16 void Select(HuffmanTree HT,int end,int &s1,int &s2); 17 18 void HuffmanCoding(HuffmanTree &HT,HuffmanCode &HC,int w[],int n) 19 { 20 if(n <= 1) 21 { 22 return; 23 } 24 25 int m = 2*n-1,i,s1 = 1,s2 = 2; 26 char *col; 27 HT = (HuffmanTree)malloc(sizeof(HTNode)*(m+1));//这里0号单元没有使用 28 HuffmanTree pt = HT; 29 pt++; 30 31 for(i = 1;i <= n;i++,w++,pt++) 32 { 33 pt->weight = *w; 34 pt->left = 0; 35 pt->right = 0; 36 pt->parent = 0; 37 } 38 for(;i <= m;i++,pt++) 39 { 40 pt->weight = 0; 41 pt->left = 0; 42 pt->right = 0; 43 pt->parent = 0; 44 } 45 46 for(i = n+1;i <= m;i++)//构造哈夫曼树 47 { 48 Select(HT,i-1,s1,s2); 49 HT[i].left = s1; 50 HT[i].right = s2; 51 HT[i].weight = HT[s1].weight + HT[s2].weight; 52 HT[s1].parent = i; 53 HT[s2].parent = i; 54 } 55 56 //---第一种方法求哈夫曼编码,逆序 57 /* 58 HC = (HuffmanCode)malloc(sizeof(char *)*(n+1)); 59 col = (char *)malloc(sizeof(char)*n); 60 col[n-1] = '\0'; 61 62 for(i = 1;i <= n;i++) 63 { 64 unsigned int start = n-1,p,f; 65 p = f = i; 66 while(HT[f].parent != 0) 67 { 68 f = HT[f].parent; 69 if(HT[f].left == p) 70 { 71 col[--start] = '0'; 72 } 73 else if(HT[f].right == p) 74 { 75 col[--start] = '1'; 76 } 77 p = f; 78 } 79 HC[i] = (char *)malloc(sizeof(char)*(n-start)); 80 strcpy(HC[i],&col[start]); 81 printf("%s\n",HC[i]); 82 } 83 84 free(col); 85 */ 86 87 //---第二种方法求哈夫曼编码,正序 88 for(i = 1;i <= m;i++) 89 { 90 HT[i].weight = 0; 91 } 92 93 col = (char *)malloc(sizeof(char)*n); 94 HC = (HuffmanCode)malloc(sizeof(char *)*(n+1)); 95 //p作为循环终止条件,当遍历完成后p会退回到树根的parent即0,此时应该终止循环,而往下倒叶子节点时是不会为0的,因此可以作为循环条件 96 int p = m,colen = 0; 97 98 while(p) 99 { 100 if(HT[p].weight == 0) 101 { 102 HT[p].weight = 1; 103 if(HT[p].left != 0) 104 { 105 p = HT[p].left; 106 col[colen++] = '0'; 107 } 108 else if(HT[p].right == 0) 109 { 110 HC[p] = (char *)malloc(sizeof(char)*(colen+1)); 111 strncpy(HC[p],col,colen); 112 HC[p][colen] = '\0'; 113 } 114 } 115 else if(HT[p].weight == 1) 116 { 117 HT[p].weight = 2; 118 if(HT[p].right != 0) 119 { 120 p = HT[p].right; 121 col[colen++] = '1'; 122 } 123 } 124 else 125 { 126 HT[p].weight = 0; 127 p = HT[p].parent; 128 colen--;//变量名写准了,不能写错 129 } 130 } 131 132 } 133 134 void Select(HuffmanTree HT,int end,int &s1,int &s2)//从1到end之间选择最小的2个元素的下标 135 { 136 int i = 1; 137 unsigned int min1,min2;//min1和min2存放parent为0的最小的2个元素 138 139 while(HT[i].parent != 0 && i <= end)//寻找第一个未访问的元素下标,if还是while一定要判断准确了,脑子清楚,不要犯低级错误 140 { 141 i++; 142 } 143 if(i == end+1) 144 { 145 return; 146 } 147 s1 = i; 148 min1 = HT[i].weight; 149 i++; 150 while(HT[i].parent != 0 && i <= end)//寻找第二个未访问的元素下标,!还是不!一定要判断准确了才行,逻辑要理清楚 151 { 152 i++; 153 } 154 if(i == end+1) 155 { 156 return; 157 } 158 s2 = i; 159 min2 = HT[i].weight; 160 i++; 161 if(min1 > min2) 162 { 163 unsigned int temp = min1; 164 min1 = min2; 165 min2 = temp; 166 temp = s1; 167 s1 = s2; 168 s2 = temp; 169 } 170 for(;i <= end;i++) 171 { 172 if(HT[i].parent == 0) 173 { 174 if(HT[i].weight < min1) 175 { 176 s2 = s1; 177 s1 = i; 178 min2 = min1; 179 min1 = HT[i].weight; 180 } 181 else if(HT[i].weight < min2) 182 { 183 s2 = i; 184 min2 = HT[i].weight; 185 } 186 } 187 } 188 }
main.cpp
1 #include "huffmanTree.h" 2 3 int main() 4 { 5 int a[4] = {4,2,1,5}; 6 HuffmanTree ht; 7 HuffmanCode hc; 8 HuffmanCoding(ht,hc,a,4); 9 for(int i = 1;i <= 4;i++) 10 { 11 //printf("%d %s \n",ht[i].weight,hc[i]); 12 printf("%s\n",hc[i]); 13 } 14 15 system("pause"); 16 return 0; 17 }