Huffman tree, also known as the optimal binary tree, is a tree with the shortest length of the weighted path, which can be used to construct the optimal coding for information transmission and data compression, and is a widely used two-fork tree.
several basic concepts related to:
1. path : The branching sequence from one node to another in the tree forms the path between two nodes
2. path length : The number of branches on the path is called the path length
3. the path length of the tree : the length of the path from the root to each node and the length of the path called the tree
4. Right of Node : Give a value to the node in the tree, which is called the right of the node
5. weighted path length : The product of the path length of the node to the root and the right of the node, known as the weighted path length of the node
6. the weighted path length of the tree : The sum of the weighted path lengths of all leaf nodes in the tree, usually recorded as WPL
7. The optimal binary tree : In the number of leaves N and the weight of each leaf determined by the conditions, the tree with the right path length WPL value of the two-tree is called the optimal binary tree. The establishment of Huffman tree
Huffman first given by the establishment of the optimal binary tree with the general rules of the algorithm, commonly known as Huffman algorithm. The description is as follows:
1): initialization : According to the given n weights (w1,w2,..., WN), the construction of the N Tree of the forest set F={t1,t2,..., tn}, where each of the binary tree ti only has a weight of the root node of the WI, the left and right subtree are empty.
2): Find the smallest tree and construct a new tree : In the forest set F, the tree with the smallest weight of two roots is constructed as a new two-fork tree, and the root node of the new two-fork tree is a newly added node, whose weight is the sum of the weights of the left and right subtrees.
3): Delete and insert : In the Forest collection F, delete the tree with the least weight of the two selected roots, and add the newly constructed two fork tree to the forest set F.
4): repeat 2 and 3 steps until the forest set F contains only one tree, this tree is Huffman tree, that is, the best binary tree. As a result of the 2 and 3 steps repeat every time, delete two trees, add a tree, so 2) and 3 steps repeat n-1 time can get Huffman tree.
The following figure shows the establishment of an optimal binary tree with 4 leaves and a weighted value of {9,6,3,1} respectively.
C + + class template Construction Huffman tree the node structure of Huffman tree
/* Huffman tree Node definition *
/template <typename t>
struct huffmannode
{
//initialization
Huffmannode (T K, huffmannode<t>* l,huffmannode<t>* R): Key (k), Lchild (L), Rchild (R), flag (0) {}
T key; Node weights
huffmannode<t>* lchild//node left child
huffmannode<t>* rchild;//node right child
int flag; Flag to determine whether to remove from the forest
};
the abstract data type of Huffman tree
Template <typename t>
class Huffman
{public
:
void Preorder (); Pre-sequence Traversal huffman tree
void Inorder (); In-sequence traversal huffman tree
void Postorder (); After the subsequent traversal Huffman tree
void creat (T a[],int size);//Create Huffman tree
void Destory (); Destroy Huffman tree
void print (); Print Huffman tree
void my_sort (int size);
Huffman (): root (NULL) {}
~huffman () {
destory (root);
}
Private:
void Preorder (huffmannode<t>* pnode); Pre-sequence traversal binary tree
void inorder (huffmannode<t>* pnode); The middle sequence traverses the binary tree
void Postorder (huffmannode<t>* pnode); Subsequent traversal of the binary tree
void print (huffmannode<t>* pnode); Print binary tree
void Destory (huffmannode<t>* pnode); Destroy the binary tree
huffmannode<t>* root;// Haffman node
huffmannode<t>* forest[maxsize]; Using an array to store the root node of the tree in the forest
;
Concrete Implementation
/* Write sort */template <typename t> void huffman<t>::my_sort (int size) {for (int i=0;i<size-1;i++) {
for (int j=i+1;j<size;j++) {if (Forest[i]->key > Forest[j]->key) {
Swap (forest[i],forest[j]);
else continue;
}
}
};
/* Create Huffman Tree */template <typename t> void huffman<t>::creat (T a[],int size) {int j,k=0; /* Each node as a forest * * for (int i=0; i<size; i++) {huffmannode<t>* ptr = new huffmannode<t> (a[i)
, null,null); Forest[i] = ptr;
The two-way queue is joined by an element} for (int i=0; i<size-1; i++) {/* Sorting the tree with the smallest root node weights/my_sort (size+k);
for (j=0; j + +) {if (forest[j]->flag!=1 && forest[j+1]->flag!= 1) { /* Build a new node */huffmannode<t>* node = huffmannode<t> (Forest[j]->key + forest[j+1 ]->key,forEst[j],forest[j+1]);
* * New node into the forest/forest[size+k] = node;
k++;
/* Delete the two trees with the smallest weight of the tree * * Forest[j]->flag = 1;
Forest[j+1]->flag = 1;
Break
else continue;
} root = Forest[size+k-1];
}; /* Pre-order Traversal Huffman tree/template <typename t> void huffman<t>::p reorder (huffmannode<t>* pnode) {if Pnode!= NU
LL) {cout << pnode-> key;
Preorder (Pnode->lchild);
Preorder (Pnode->rchild);
}
};
Template <typename t> void huffman<t>::p reorder () {preorder (root); /* In-order traversal Huffman tree/template <typename t> void Huffman<t>::inorder (huffmannode<t>* pnode) {if Pnode!= NUL
L) {inorder (pnode->lchild);
cout << pnode-> key;
Inorder (Pnode->rchild);
}
}; Template <typename t> void Huffman<t>::inordER () {inorder (root);}; /* Subsequent Traversal Huffman tree/template <typename t> void huffman<t>::p ostorder (huffmannode<t>* pnode) {if Pnode!= N
ull) {postorder (pnode->lchild);
Postorder (Pnode->rchild);
cout << pnode-> key;
}
};
Template <typename t> void huffman<t>::p Ostorder () {postorder (root);
/* Print Huffman Tree * * Template <typename t> void Huffman<t>::p rint (huffmannode<t>* pnode) {if (Pnode!= NULL)
{cout << "current node:" << pnode-> key << "."
if (pnode-> lchild!= NULL) cout << "Its left child node is:" << pnode->lchild->key << "."
else cout << "It has no left child."
if (pnode-> rchild!= NULL) cout << "Its right child node is:" << pnode->rchild->key << "."
else cout << "It doesn't have a right child."
cout << Endl;
Print (Pnode->lchild); Print (PnodE->rchild);
}
};
Template <typename t> void huffman<t>::p rint () {print (root);
};
/* Destroy Huffman Tree/template <typename t> void huffman<t>::d estory (huffmannode<t>* pnode) {if (pnode!= NULL)
{destory (pnode->lchild);
Destory (Pnode->rchild);
Delete Pnode;
Pnode = NULL;
}
}; Template <typename t> void huffman<t>::d estory () {destory (root);
Huffman Tree Code test
int main ()
{
huffman<int> huff;
int a[] = {10,20,30,40};
Huff.creat (a,4);
Huff.print ();
return 0;
}
Output Results:
Current node: 100. Its left child node is: 40. Its right child node is:
Current node: 40. It has no left child. It has no right child.
Current node: 60. Its left child node is: 30. Its right child node is:
Current node: 30. It has no left child. It has no right child.
Current node: 30. Its left child node is: 10. Its right child node is:
Current node: 10. It has no left child. It has no right child.
Current node: 20. It has no left child. It has no right child.
Yesterday afternoon began to write, the original use of deque bidirectional queues to store the root node of the forest tree, the result is sorted to find the right value of the two trees when the problem encountered trouble, a number of different ways are compiled errors, tortured for several hours. Later chose to use an array to store, this afternoon, try to write a bit, finally the whole out, still need to optimize, share it, the whole thinking process has a comment, down slowly change. Below look Huffman code.
#include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct{unsigned int weight;
unsigned int parent,lchild,rchild;
}htnode,*huffmantree;
typedef char **huffmancode;
int Select (Huffmantree HT, int n, int *s1, int *s2) {//in HT[1..N] Select two nodes with parent 0 and weight,//whose ordinal number is S1 and S2 respectively.
int I,j,k,flag;
int count = 0;
For (I=1 i<=n; i++) {if (ht[i].parent = = 0) count++;
} if (count = = 0) return 1;
*S1 = 0;
*S2 = 0;
For (I=1 i<=n; i++) {if (ht[i].parent!= 0) continue;
if (Ht[i].weight < ht[*s1].weight) *s1 = i;
for (int j=1; j<=n; J + +) {if (ht[j].parent!= 0) continue;
if (Ht[j].weight < ht[*s2].weight && J!= *s1) *s2 = j;
} void Create_huffmantree (Huffmantree ht,huffmancode hc,int *w,int n) {int start;
Char *CD; and find the N-character Huffman code HC int I, M, S1=0, s2=0;
unsigned int c, F;
if (n<=1) return;
m = 2 * n-1; HT = (Huffmantree) malloc ((m+1) * sizeof (Htnode));
Unit No. 0 is not used ht[0].weight = 99999;
For (I=1 i<=n; i++) {//initialize ht[i].weight=w[i-1];
ht[i].parent=0;
Ht[i].lchild=0;
Ht[i].rchild=0;
for (i=n+1; i<=m; i++) {//Initialize ht[i].weight=0;
ht[i].parent=0;
Ht[i].lchild=0;
Ht[i].rchild=0;
For (i=n+1 i<=m; i++) {//Kenhaffman//In ht[1..i-1] Select two nodes with parent 0 and weight,//whose ordinal numbers are S1 and S2 respectively.
Select (HT, I-1, &S1, &S2);
printf ("%d%d\n", 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; //---Huffman encoding for each character from leaf to root---cd = (char *) malloc (n*sizeof (char)); Allocation of work space for coding cd[n-1] = ';
The ending character of the encoding.
For (I=1 i<=n; ++i) {//character Fu Tiu Huffman encoding start = n-1; Encoder terminator position for (c=i, f=ht[i].parent; f!=0 c=f, f=ht[f].parent)//from leaf to root reverse code if (ht[f].lchild==c
) Cd[--start] = ' 0 ';
else Cd[--start] = ' 1 ';
Hc[i] = (char *) malloc ((N-start) *sizeof (char)); Allocating space for the first character encoding (Hc[i], &cd[start]); strcpy Copy the Encoding (string) from the CD to the HC Free (CD);
Free workspace}//huffmancoding void huffmancoding (huffmantree ht,huffmancode hc,int *w,int n) {int start;
Char *CD;
and find n characters Huffman code HC int I, M, S1=0, s2=0;
unsigned int c, F;
if (n<=1) return;
m = 2 * n-1; HT = (Huffmantree) malloc ((m+1) * sizeof (Htnode));
Unit No. 0 is not used ht[0].weight = 99999;
For (I=1 i<=n; i++) {//initialize ht[i].weight=w[i-1];
ht[i].parent=0;
Ht[i].lchild=0;
Ht[i].rchild=0;
for (i=n+1; i<=m; i++) {//Initialize ht[i].weight=0;
ht[i].parent=0;
Ht[i].lchild=0;
Ht[i].rchild=0; for (i=n+1; i<=m;
i++) {//Kenhaffman///in ht[1..i-1] Select the two nodes with parent 0 and weight the smallest,//whose serial numbers are S1 and S2 respectively.
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; //---Huffman encoding for each character from leaf to root---cd = (char *) malloc (n*sizeof (char)); Allocation of work space for coding cd[n-1] = ';
The ending character of the encoding. For (I=1 i<=n; ++i) {//character Fu Tiu Huffman code start = n-1; Encoder terminator position for (c=i, f=ht[i].parent; f!=0 c=f, f=ht[f].parent)//from leaf to root reverse code if (ht[f].lchild==c
) Cd[--start] = ' 0 ';
else Cd[--start] = ' 1 ';
Hc[i] = (char *) malloc ((N-start) *sizeof (char)); Allocating space for the first character encoding (Hc[i], &cd[start]); strcpy Copy the Encoding (string) from the CD to the HC Free (CD);
Free working space char *code;
Decoding code = (char *) malloc (50*sizeof (char));
printf ("Please Enter code:"); scanf ("%s", code);
Htnode pnode = ht[m];
for (int q=0; code[q]!= '; q++ ') {if (code[q] = = ' 0 ') {pnode = Ht[pnode.lchild];
if (Pnode.rchild = = 0 && pnode.lchild = 0) {printf ("%d", pnode.weight);
Pnode = Ht[m];
} if (code[q] = = ' 1 ') {pnode = Ht[pnode.rchild];
if (Pnode.rchild = = 0 && pnode.lchild = 0) {printf ("%d", pnode.weight);
Pnode = Ht[m];
//huffmancode int main () {int I,n,choice}}}}}
int *w;
Huffmantree HT;
Huffmancode HC;
printf ("Node number:"); scanf ("%d", &n);
Number of weights w= (int *) malloc (n*sizeof (int));
printf ("Input Weights:");
for (i=0;i<n;i++)//Input weights scanf ("%d", &w[i]); hc= (char * *) malloc ((n+1) *sizeof (char*)); 0 Space Unused ht= (Huffmantree) malloc ((2*n+1+1) *sizeof (Htnode));0 space is not used printf ("encoding option 1 only, decoding please choose 2:");
scanf ("%d", &choice);
if (choice = = 1) {create_huffmantree (ht,hc,w,n); for (i = 1; i<n+1; i++) {printf ("%s\n", Hc[i]); Output Huffman code free (Hc[i]);
Free Space}} if (choice = 2) huffmancoding (ht,hc,w,n);
Free (HC);
Free (HT);
return 0; }