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 }

 

posted @ 2012-12-06 22:40  maowang  阅读(1240)  评论(0编辑  收藏  举报