I. Definition

A Balanced Binary Tree is also called an AVL Tree (different from the AVL algorithm) and has the following features: it is an empty tree or its left and right subtree. The absolute value of the height difference cannot exceed 1, and both left and right subtree are a balanced binary tree. Common algorithms for balanced binary trees include red/black trees, AVL trees, Treap trees, and stretch trees.

The balanced binary tree is introduced on the binary sorting tree (BST). To solve the imbalance of the binary sorting tree, the time complexity is greatly reduced, so AVL will stay (BST) the best time complexity O (logn), so every insertion and deletion must ensure the balance of the binary tree. The balanced binary tree is shown in Figure 1.

Figure 1 (a) balanced binary tree (B) unbalanced Binary Tree

Ii. Functions

For a Binary Search Tree, the expected height (that is, when a Balance Tree is used) is log2n, and the time complexity of each operation (O (log2n )) at the same time, this is also decided. However, in some extreme cases (such as when the inserted sequence is ordered), the binary search tree degrades to an approximate chain or chain, the time complexity of its operations degrades to linear, that is, O (n ). We can avoid this problem by creating a binary search tree in randomization mode. However, after multiple operations, we always choose to replace the successor of the node to be deleted, which will reduce the number of nodes on the right, so that the tree is sunk to the left. This also damages the balance of the tree and reduces the time complexity of its operations.

A Balanced Binary Tree has the following properties: it is an empty Tree or its left and right subtree. The absolute value of the height difference cannot exceed 1, both left and right Subtrees are balanced binary trees. Common algorithms include red/black trees, AVL, Treap, and stretch trees. In the balanced binary search tree, we can see that its height is generally well maintained at O (log2n), greatly reducing the operation time complexity.

Iii. Dynamic Balancing Technology 1. Dynamic Balancing Technology

Adelson-Velskii and Landis propose a technique to dynamically maintain a binary cross. 1. Dynamic Balancing

Adelson-Velskii and Landis propose a method to dynamically maintain the balance of the binary sorting tree. The basic idea is that when a knot is inserted during the construction of the binary sorting tree, first, check whether the balance of the tree is damaged due to insertion. If the balance of the tree is damaged due to the insertion of nodes, find the minimum imbalance subtree, to achieve a new balance, adjust the connections between nodes in the sub-tree with the minimum imbalance while maintaining the ordering tree feature. Generally, the balanced binary sorting tree is called AVL Tree.

2. Minimum imbalance subtree

Use the node closest to the inserted node and the absolute value of the balance factor greater than 1 as the Child tree of the root node. To simplify the discussion, assume that the root node of the sub-tree with the minimum imbalance of the binary sorting tree is A, then the rule of adjusting the sub-tree can be summarized into the following four situations:

(1) LL type:

The new node X is inserted in the left subtree of the left child of. The adjustment method is shown in figure 2 (). In the figure, node A is centered on Node B and is transferred from the top right of Node B to the bottom right of Node B, making node A the right child of Node B.

Figure 2

(2) RR type:

The new node X is inserted in the right subtree of the right child of. See figure 2 (B ). In the figure, node A is centered on Node B and is transferred from the top left of Node B to the bottom left of Node B, making node A the left child of Node B.

(3) LR type:

The new node X is inserted in the right subtree of the left child of. The adjustment method is shown in figure 2 (c ). There are two steps: the first step is to take X as the axis, and convert B from the top left of X to the bottom left of X, so that B becomes the left child of X, and X becomes the left child of. The second step is the same as the LL type (X should be used as the axis ).

(4) RL:

The new node X is inserted in the left subtree of the right child of. The adjustment method is shown in figure 2 (d ). There are two steps: the first step is to take X as the axis, and convert B from the top right of X to the bottom right of X, so that B becomes the right child of X, and X becomes the right child of. The second step is the same as the RR type (X should be used as the axis ).

The actual insertion may be more complex than figure 2. Because node A and Node B may have Subtrees. The following example shows how to insert a set of record keywords in the following order: 4, 5, 7, 2, 1, 3, 6, the process of generating and adjusting a binary Balance Tree is shown in figure 3.

In Figure 3, when a node with a keyword of 3 is inserted, the ancestor of the equilibrium factor 2 closest to node 3 is root node 5. Therefore, the first rotation should take node 4 as the axis, and switch Node 2 from the top left of node 4 to the bottom left, so that the left child of node 5 is node 4, the left child of node 4 is node 2, and the left child of node 4 is the right child of Node 2. The second step is to use node 4 as the axis and convert the data according to the LL type. This insertion and adjustment balancing method can be compiled into algorithms and programs, which will not be discussed here.

Figure 3 balanced binary tree Creation

3. Code Implementation

**Utl. h**

# Ifndef UTL_H _ # define UTL_H _/** sorts out some common functions, such as memory management */# include <stdio. h> # include <stdlib. h>/* apply for memory */inline void * xalloc (int size) {void * p; p = (void *) malloc (size ); /* application failed */if (p = NULL) {printf ("alloc error \ n"); exit (1);} return p ;} /* memory release */# define xfree (p) free (p) # endif

__Avl. h__

# Ifndef AVL_H __# define AVL_H _/** avl tree data structure and related operations */# include <stdio. h> # include <stdlib. h> struct AVLTree {unsigned int nData;/* store data */struct AVLTree * pLeft;/* points to the left subtree */struct AVLTree * pRight; /* point to the right subtree */int nHeight;/* balance of the tree */};/* insert operation */struct AVLTree * insert_tree (unsigned int nData, struct AVLTree * pNode);/* find and return 1; otherwise, return 0 */int find_tree (unsigned int data, struct AVLTree * pRoot);/* Delete, delete all nodes */void delete_tree (struct AVLTree ** ppRoot);/* print operation */void print_tree (struct AVLTree * pRoot); # endif

__Avl. c__

# Include "AVL. H "# include" utl. H "static int max (int A, int B); static int height (struct avltree * pnode ); /* rotation operation */static struct avltree * singlerotatewithleft (struct avltree * pnode); static struct avltree * singlerotatewithright (struct avltree * pnode ); static struct avltree * doublerotatewithleft (struct avltree * pnode); static struct avltree * doublerotatewithright (struct avltree * pnode); struct avltree * inser T_tree (unsigned int ndata, struct avltree * pnode) {If (null = pnode) {pnode = (struct avltree *) xalloc (sizeof (struct avltree )); pnode-> ndata = ndata; pnode-> nheight = 0; pnode-> pleft = pnode-> pright = NULL;} else if (ndata <pnode-> ndata) /* insert to the left subtree */{pnode-> pleft = insert_tree (ndata, pnode-> pleft); If (height (pnode-> pleft) -Height (pnode-> pright) = 2)/* AVL Tree imbalance */{If (ndata <pnode-> pleft-> N Data) {/* insert to the left of the Left subtree for single rotation */pnode = singlerotatewithleft (pnode);} else {/* insert to the right of the Left subtree, perform double rotation */pnode = doublerotatewithleft (pnode) ;}} else if (ndata> pnode-> ndata) /* insert to the right subtree */{pnode-> pright = insert_tree (ndata, pnode-> pright); If (height (pnode-> pright) -Height (pnode-> pleft) = 2)/* AVL Tree imbalance */{If (ndata> pnode-> pright-> ndata) {/* insert to the right subtree for single rotation */pnode = singlerotatewithright (pnode);} el Se {/* insert to the left of the right subtree and perform double rotation */pnode = doublerotatewithright (pnode );}}} pnode-> nheight = max (height (pnode-> pleft), height (pnode-> pright) + 1; return pnode ;} /* Delete tree */void delete_tree (struct avltree ** pproot) {If (null = pproot | null = * pproot) return; delete_tree (& (* pproot) -> pleft); delete_tree (& (* pproot)-> pright); xfree (* pproot); * pproot = NULL ;} /* traverse all nodes of the print tree in the middle order. Because the left node <parent node <right node, the size of the printed data is Added */void print_tree (struct avltree * proot) {If (null = proot) return; static int n = 0; print_tree (proot-> pleft ); printf ("[% d] ndata = % u \ n", ++ N, proot-> ndata); print_tree (proot-> pright);}/** search operation, 1 is returned. Otherwise, 0 * data is returned. The data to be searched is * proot: AVL tree pointer */INT find_tree (unsigned int data, struct avltree * proot) {static int K = 1;/* search times */If (null = proot) {printf ("not find % d times \ n", k); Return 0 ;} if (Data = Proot-> ndata) {printf ("find: % d times \ n", k); return 1;} else if (Data <proot-> ndata) {++ K; return find_tree (data, proot-> pleft);} else if (data> proot-> ndata) {++ K; return find_tree (data, proot-> pright );}} static int max (int A, int B) {return (A> B? A: B);}/* return the node's balance */static int height (struct avltree * pnode) {If (null = pnode) Return-1; return pnode-> nheight ;} /*************************************** * *************************** pnode-> pleft/\ pnode-> pleft ==> pnode \/pnode-> pleft-> pright ******************** **************************************** * *******/static struct avltree * singlerotatewithleft (struct avltree * pnode) {struct avltree * pnode1; pnode1 = pnode-> pleft; pnode-> pleft = pnode1-> pright; pnode1-> pright = pnode;/* the node location has changed, the height of the node to be updated */pnode-> nheight = max (height (pnode-> pleft), height (pnode-> pright) + 1; pnode1-> nheight = max (height (pnode1-> pleft), pnode-> nheight) + 1; return pnode1 ;} /*************************************** * *************************** pnode-> pright \/pnode-> pright ==> pnode/\ pnode-> pright-> pleft ******************** **************************************** * *******/static struct avltree * singlerotatewithright (struct avltree * pnode) {struct avltree * pnode1; pnode1 = pnode-> pright; pnode-> pright = pnode1-> pleft; pnode1-> pleft = pnode;/* the node location has changed, the height of the node to be updated */pnode-> nheight = max (height (pnode-> pleft), height (pnode-> pright) + 1; pnode1-> nheight = max (height (pnode1-> pright), pnode-> nheight) + 1; return pnode1;} static struct avltree * doublerotatewithleft (struct avltree * pnode) {pnode-> pleft = singlerotatewithright (pnode-> pleft); Return singlerotatewithleft (pnode);} static struct avltree * doublerotatewithright (struct avltree * pnode) {pnode-> pright = singlerotatewithleft (pnode-> pright); Return singlerotatewithright (pnode );}

__Test Functions__

#include <stdio.h>#include <time.h>#include "avl.h"int main(){ int i,j; AVLTree* pRoot = NULL; srand((unsigned int)time(NULL)); for (i = 0; i < 10; ++i) { j = rand(); printf("%d\n", j); pRoot = Insert(j, pRoot); } PrintTree(pRoot); DeleteTree(&pRoot); return 0;}

Iv. References

1. http://sjjg.js.zwu.edu.cn/SFXX/chazhao/chazhao7.3.2.2.html

2. baike.baidu.com/view/593144.htm

3. http://caoruntao.iteye.com/blog/1013550