構建Huffman樹:
1.將給定的n個權值看作n棵只有結點無左右孩子的二叉樹,組合成一個集合HT。
2.從集合HT中選出2棵權值最小的二叉樹,組成一棵新的二叉樹,其權值為這兩棵二叉樹的權值之和。
3.將步驟2中選出的二叉樹從集合HT中刪去,同時將步驟2中新的二叉樹加入到集合HT中。
4.重復步驟2和步驟3,直到集合HT中只含有一棵樹,這棵樹就是Huffman樹。
偽代碼:
typedefstruct//定義結構體
{
intweight;//保存權值
intparent, lchild, rchild;//保存父節點、左右孩子的節點值
}HuffmanNode, *HuffmanTree;
typedefchar**HuffmanCode;//用來存儲哈夫曼編碼
procHuffmanCoding(HuffmanTree &HT,int*w,intn)//編碼函數定義
if(n <= 1)then Error();
m := 2 * n - 1;//n nodes create huffman tree need 2n-1 nodes
HT:= (HuffmanNode*)malloc((m +1) *sizeof(HuffmanNode));//HT存放Huffman tree的所有節點,申請m+1個位置
memset(HT, 0, (m + 1)*sizeof(HuffmanNode));//對所有節點初始化為0
//setthe n nodes
fori from 1 to n
HT[i].weight := *w++;//初始化各節點的權值
//createHuffman tree
fori from n + 1 to m//從HT的第n+1個位置開始
select(HT, i - 1, s1,s2);//選擇剩余節點中權值較小的s1和s2
HT[s1].parent := i;//s1,s2的父節點都是當前結點
HT[s2].parent := i;
HT[i].lchild := s1;
HT[i].rchild := s2;
HT[i].weight :=HT[s1].weight + HT[s2].weight;
end{for}
HC := (HuffmanCode)malloc((n + 1) *sizeof(char*));
char*cd = (char*)malloc(n *sizeof(char));//申請n個位置,最后一位存放結束符
cd[n - 1] ='\0';
fori from 1 to n
start = n - 1;
for(c= i, f = HT[i].parent; f != 0; c = f, f = HT[f].parent)
if(HT[f].lchild == c)
cd[--start] ='0';//cd從后往前依次存放
else
cd[--start] ='1';
end{for}
HC[i] = (char*)malloc((n - start) *sizeof(char));
strcpy(HC[i],&cd[start]);
end{for}
end{proc}
源碼:
#include
#include
#include
usingnamespacestd;
/*哈夫曼樹的存儲結構,它是二叉樹*/
typedefstruct
{
intweight;//保存權值
intparent, lchild, rchild;//保存父節點、左右孩子的節點值
}HuffmanNode, *HuffmanTree;
typedefchar**HuffmanCode;//用來存儲哈夫曼編碼
voidHuffmanCoding(HuffmanTree &HT,int*w,intn);//Huffman編碼函數
voidselect(HuffmanTree HT,intn,int&s1,int&s2);//選擇書中節點值較小的兩個節點
voidError(char*message);//顯示錯誤信息
intmain(intargc,char* argv[])
{
inti,n;
int*w;
HuffmanCode HC;
HuffmanTree HT;
cout<<"Enter the size of the code:";
cin>>n;
w=(int*)malloc(n*sizeof(int));
cout<<"Enter the weight of the code:";
for(i=0;i
cin>>w[i];
cout<<"The Huffmancode is:"<
HuffmanCoding(HT, w, n);
system("pause");
}
voidHuffmanCoding(HuffmanTree &HT,int*w,intn)
{
if(n <= 1)
Error("code is small");
intm = 2 * n - 1;//n nodes create huffman tree need2n-1 nodes
HT = (HuffmanNode*)malloc((m +1) *sizeof(HuffmanNode));//Huffman tree的所有節點
ints1, s2;//record the two mini weights nodes
memset(HT, 0, (m + 1)*sizeof(HuffmanNode));//對所有節點初始化為0
//setthe n nodes
for(inti = 1; i <= n; i++)
{
HT[i].weight = *w++;//初始化各節點權值
}
//創建Huffmantree
for(inti = n + 1; i <= m; ++i)
{
//選擇剩余節點中權值較小的s1和s2
select(HT, i - 1, s1,s2);
HT[s1].parent = i;
HT[s2].parent = i;
HT[i].lchild = s1;
HT[i].rchild = s2;
HT[i].weight = HT[s1].weight+ HT[s2].weight;
}
HuffmanCode HC;
intstart, c, f;
HC = (HuffmanCode)malloc((n + 1)*sizeof(char*));
char*cd = (char*)malloc(n *sizeof(char));
cd[n - 1] ='\0';
for(inti = 1; i <= n; ++i)
{
start = n - 1;
for(c= i, f = HT[i].parent; f != 0; c = f, f = HT[f].parent)
if(HT[f].lchild == c)
cd[--start] ='0';
else
cd[--start] ='1';
HC[i] = (char*)malloc((n - start) *sizeof(char));
strcpy(HC[i],&cd[start]);
}
for(inti = 1; i <= n; i++)
{
cout<
}
free(cd);
free(HC);
free(HT);
}
voidError(char*message)
{
fprintf(stderr,"Error: %s(5s will exit)",message);
cout<<"\n";
Sleep(5000);
exit(1);
}
voidselect(HuffmanTree HT,intn,int&s1,int&s2)
{
s1 = 1;
s2 = 1;
intmin= 99999;
inti;
//選擇未被使用的第一個節點,
for(i = 1; i <= n; ++i)
{
if(HT[i].parent == 0)
{
min = HT[i].weight;
break;
}
}
//findthe mini s1
for(intp =1; p <= n; ++p)
{
if(0== HT[p].parent && min >= HT[p].weight)
{
s1 = p;
min = HT[p].weight;
}
}
//findthe s2
min = 99999;
for(intq =1; q <= n; ++q)
{
if(0== HT[q].parent && min >= HT[q].weight )
{
if(q == s1)
continue;
s2 = q;
min = HT[q].weight;
}
}
}
運行結果示例: