I. What is an optimal binary tree?
In my personal understanding, the optimal binary tree is to form a tree through a combination of given destination weighted nodes (individual nodes. minimum tree weight. the optimal binary tree is a binary tree with the shortest length of the weight path. The shape of the optimal binary tree varies according to the number of nodes and weights. What they have in common is:All nodes with weights are leaf nodes. A node with a smaller weight has a longer path to the root node.
Official definition:
In wl, W2 ,..., Among all the Binary Trees composed of N leaves of WN, the binary tree with the minimum length of the weight path (that is, the minimum cost) is calledOptimal Binary TreeOrHarman tree.
Ii. Let's clarify several concepts:
1. Path Length
The branches that the tree experiences from one node to another constitute the number of branches on the path between the two nodes, which is called its path length.
2. Tree path length
The tree path length is the sum of the path lengths from the root to each node in the tree. In a binary tree with the same number of nodes, the path length of the Complete Binary Tree is the shortest.
3. The length of the tree's weighted path (weighted path length of tree, abbreviated as WPL)
Node permission: In some applications, assign a meaningful real number to the node in the tree.
Length of the weighted path of a node: The product of the path length between the node and the root of the tree and the permission on the node.
Length of the tree's weighted path(Weighted path length of tree): defines the sum of the length of the weighted path of all leaf nodes in the tree. It is usually recorded:
Where:
N indicates the number of leaf nodes.
WI and Li indicate the weight of the leaf node KI and the path length between the root node Ki.
The length of the tree's weighted path is also known as the cost of the tree.
Iii. Use an example to understand the above concepts
[Example] Four Leaf nodes A, B, C, and D are given with weights 7, 5, 2, and 4, respectively. Construct the three Binary Trees (and many other trees) as shown in. Their weighted path lengths are:
(A) WPL = 7*2 + 5*2 + 2*2 + 4*2 = 36
(B) WPL = 7*3 + 5*3 + 2*1 + 4*2 = 46
(C) WPL = 7*1 + 5*2 + 2*3 + 4*3 = 35
The WPL of the (c) tree is the smallest, which can be verified.
Note:
① When the weights on the leaves are the same, the full binary tree must be the optimal binary tree; otherwise, the full binary tree is not necessarily the optimal binary tree.
② In the optimal binary tree, the higher the weight, the closer the leaves are from the root.
③ The form of the optimal binary tree is not unique, and the WPL is the smallest.
Iv. Harman Algorithm
For the method of constructing the optimal binary tree based on the given number of leaves and their weights, this algorithm is called the Harman algorithm because it is proposed by Harman. The basic idea is:
(1) Based on the given n weights wl, W2 ,..., Wn: Forests of N Binary Trees F = {T1, T2 ,..., Tn}, where each binary tree TI has only one root node with the weight of Wi, and left and right subtree are empty.
(2) in forest F, select the tree with the smallest root node weight (when there are more than two trees, you can select two trees) and combine the two trees into a new tree, to ensure that the new tree is still a binary tree, you need to add a new node as the root of the new tree, and use the root of the selected two trees as the left and right children of the new root (the left and right do not matter ), use the sum of the weights of the two children as the weights of the new roots.
(3) Repeat the New Forest F (2) until only one tree is left in forest F. This tree is the Harman tree.
Note:
① N binary trees in the initial forest, each of which has an isolated node. They are both roots and leaves.
② The Harman tree with N leaves needs to be merged n-1 times to generate n-1 new nodes. In the final result, there are 2n-1 nodes in the Harman tree.
③ A strict binary tree does not have a branch node with a level of 1.
V. Implementation of the optimal binary tree algorithm
When constructing a user-defined tree, you can set a structure array huffnode to store the information of each node in the User-Defined tree. According to the nature of the binary tree, there are 2-1 nodes in the User-Defined tree with N leaf nodes, therefore, the size of the array huffnode is set to 2n-1. The structure of the array elements is as follows:
Weight |
Lchild |
Rchild |
Parent |
The weight domain stores the node weights. The lchild and rchild fields respectively store the numbers of the left and right child nodes of the node in the array huffnode to establish the relationship between the nodes. To determine whether a node has been added to the user tree to be created, you can use the value of the parent field. The initial value of parent is-1. When a node is added to the tree, the value of parent of this node is the serial number of its parent node in the array huffnode, and it will not be-1. When constructing the Harman tree, the N leaf nodes formed by n characters are first stored in the first N components of the array huffnode. Then, based on the basic idea of the Harman method described above, the two child trees are constantly merged into a larger child tree. The root node sequence of each new child tree is placed behind the first N components in the huffnode array.
Specific implementation:
1) Storage Structure
# Define n 100 // Number of leaf nodes # define M 2 * n-1 // total number of nodes in the tree typedef struct {floatweight; // set the weight value to greater than zero intlchild, rchild, parent; // both left and right children and parent-parent pointer} htnode; typedef htnode huffmantree [m]; // The Harman tree is a one-dimensional array.
(2) Array Construction of the Heman Algorithm
Void createhuffmantree (huffmantree t) {int I, P1, P2; // construct a user-defined tree. M-1] is the root node inithuffmantree (t ); // t initialize inputweight (t); // enter the leaf weight to T [0 .. n-1 1] weight domain for (I = N; I <m; I ++) {selectmin (T, I-1, & P1, & p2 ); // merge n-1 times in total, and the new nodes are stored in T [I] in sequence. // at T [0... Select the two smallest root nodes in the I-1, whose numbers are P1 and P2 T [P1]. parent = T [P2]. parent = I; t [I]. 1 child = p1; // The root node with the minimum weight is the left child of the new node T [I]. rchild = P2; // The root node of the sub-permission is the right child of the new node T [I]. weight = T [P1]. weight + T [P2]. weight;} // For} // createhuffman
C language:
# Include "stdio. H "# include" stdlib. H "# define M 100 struct ptree // defines the Binary Tree node type {int W; // defines the node weight value struct ptree * lchild; // defines the left subnode pointer struct ptree * rchild; // define the right child node pointer}; struct pforest // define the linked list node type {struct pforest * link; struct ptree * root;}; int WPL = 0; // initialize wtl to 0 struct ptree * hafm (); void travel (); struct pforest * inforest (struct pforest * F, struct ptree * t ); void travel (struct ptree * head, int N) {// Traverse struct ptree * P; P = head; If (P! = NULL) {If (P-> lchild) = NULL & (p-> rchild) = NULL) // if it is a leaf node {printf ("% d", p-> W); printf ("the hops of the node is: % d/N", N ); WPL = WPL + N * (p-> W); // calculate the weight} // iftravel (p-> lchild, n + 1); travel (p-> rchild, n + 1);} // If} // travel struct ptree * hafm (int n, int W [m]) {struct pforest * P1, * P2, * F; struct ptree * ti, * t, * T1, * t2; int I; F = (pforest *) malloc (sizeof (pforest); F-> link = NULL; for (I = 1; I <= N; I ++) // generate n Binary Trees with only root nodes {Ti = (Ptree *) malloc (sizeof (ptree); // open up a new Node space Ti-> W = W [I]; // assign the node authorization value ti-> lchild = NULL; Ti-> rchild = NULL; F = inforest (F, Ti ); // place the node from top to bottom on a tree in the order of ascending weights} // forwhile (f-> link )! = NULL) // There are at least two binary trees {p1 = f-> link; P2 = p1-> link; F-> link = P2-> link; // retrieve the first two shards T1 = p1-> root; t2 = P2-> root; free (P1); // release P1 free (P2 ); // release P2 t = (ptree *) malloc (sizeof (ptree); // open up a new Node space T-> W = (T1-> W) + (T2-> W); // weight addition t-> lchild = T1; t-> rchild = t2; // generate a new binary tree F = inforest (F, t);} // while p1 = f-> link; t = p1-> root; free (f); Return (t ); // return t} pforest * inforest (struct pforest * F, structptree * t) {// place the node from top to bottom on a tree in the order of Weight Ruct pforest * P, * q, * r; struct ptree * ti; r = (pforest *) malloc (sizeof (pforest )); // open up a new Node space R-> root = T; q = f; P = f-> link; while (P! = NULL) // find the insert position {Ti = p-> root; If (t-> W> Ti-> W) // If t's weight is greater than Ti's weight {q = P; P = p-> link; // P searches backward} // If else P = NULL; // force exit loop} // whiler-> link = Q-> link; q-> link = r; // R is connected to the end of Q and return (f ); // return f} void input (Int & N, int W [m]) {printf ("Please input the sum ofnode/N "); // prompt to enter the number of knots scanf ("% d", & N); // enter the number of knots printf ("Please input weight of everynode/N "); // you are prompted to enter the value of each node for (INT I = 1; I <= N; I ++) scanf ("% d", & W [I]). // input the weight of each node} int main () {struct ptree * head; int N, W [m]; input (n, W); Head = hafm (n, w); travel (Head, 0); printf ("the length of the best path iswpl = % d", WPL); // return 1 for the sum of the output best path weights ;}