[Algorithm learning] AVL balanced binary search tree principle and various Operation Programming implementation (C ++)

Source: Internet
Author: User

AVLTree (Adelson-Velskii-Landis Tree)Is a binary search tree with additional conditions. The balance condition is established to ensure that the depth of the entire tree is O (nlogn ). The balance condition is that the height difference between left and right subtree of any node cannot exceed 1.


In the following code,Programming allows you to establish, search, insert, delete, and traverse AVL trees.. C ++ class encapsulation.

Insert and delete complex operations in the AVL Tree. Here, we will explain the insert and delete operations.


AVL Tree Insertion

Inserting an element into the AVL tree may cause the tree to lose its balance. However, you only need to adjust the depth of each node that does not meet the balance on the path from the insertion point to the root node. Assume that the deepest node is X. There are four possible causes of X imbalance:

(1) the insertion point is located in the left subtree of the Left subnode of X-left.

(2) the insertion point is located at the right subtree-left and right of the Left subnode of X.

(3) the insertion point is located in the left subtree-right left of the right subnode of X.

(4) the insertion point is located in the left subtree of the right child node of X-right.


Case 1 and case 4 are symmetric and become lateral inserts, which can be solved by single rotation. In this case, 2 and 3 are symmetric and become inner inserts. Solve the problem through double rotation.

Case 1: single rotation example:



Dual rotation example for Case 2:



AVL tree deletion

Delete operations can also be divided into several situations:

First, search the tree for whether the element value of a node is equal to the element to be deleted. If not found, return directly. Otherwise, perform the following operations.

(1) The node to be deleted is the current root node T.

If left and right subtree are not empty. Delete a sub-tree with a large height.

There are two situations:

A. The height of the Left subtree is greater than that of the right subtree. Assign the largest element in the left subtree to the current root node, and then delete the node with the largest element value in the left subtree.

B. The height of the Left subtree is smaller than that of the right subtree. Assign the smallest element in the right subtree to the current root node, and then delete the node with the smallest element value in the right subtree.

If one of the left and right subtree is empty, replace the current root node with the non-empty subtree or NULL.

(2) If the element value of the node to be deleted is smaller than the tvalue of the current root node, delete it in the left subtree.

Recursive call, which is performed in the left subtree.

This is to determine whether the current root node still meets the balance condition,

If the balance condition is met, you only need to update the height information of the current root node T.

Otherwise, you need to adjust the rotation:

If the height of the Left subtree of the Left subnode of T is greater than that of the right subtree of the Left subnode of T, the corresponding single rotation is performed. Otherwise, double rotation is performed.

(3) If the element value of the node to be deleted is greater than the tvalue of the current root node, delete it in the right subtree.

The process is similar to the preceding steps.

For details, see the code.


Only the code of my programming implementation is listed here. If I find any bugs, I should forgive me and correct them!

AVLTree. h:

# Ifndef AVLTREE_H_INCLUDED # define AVLTREE_H_INCLUDED // AVL tree data structure definition typedef int ElementType; // AVL number node contains data type // Tree node typedef struct AVLNode {ElementType element; // AVLNode * left; // AVLNode * right of the left subtree of the node; // int height of the right subtree of the node; // height of the node} * AVLTree; // The AVL tree class encapsulates class CAVLTree {private: // The int getHeight (AVLTree) function for internal calls; // obtain the height of the tree void setHeight (AVLTree, int ); // set the node height // single rotation: Rotate AVLTree SingleRightRotate (AVLTree) to the right; // single rotation: Orientation Left rotation AVLTree SingleLeftRotate (AVLTree); // double rotation: Left and Right AVLTree DoubleRightRotate (AVLTree); // double rotation: Right left AVLTree DoubleLeftRotate (AVLTree); public: // default constructor CAVLTree (); // destructor ~ CAVLTree (); // create AVL Tree void createAVLTree (ElementType * data, int n); // Insert the AVLTree insertNode (AVLTree T, ElementType val ); // Delete the node AVLTree deleteNode (AVLTree T, const ElementType val) whose element value is equal to a value in the tree; // search for the node AVLTree searchNode (AVLTree, elementType); // traverses the void preOrder (AVLTree T) of the output tree in the forward order; // obtains the node AVLTree getMaxNode (AVLTree) with the largest element value in the tree ); // obtain the node AVLTree getMinNode (AVLTree); AVLTree T ;}; # endif // AVLTREE_H_INCLUDED with the smallest element value in the tree.

AVLTree. cpp:

# Include "avltree. H "# include <iostream> # include <cmath> # include <cassert> using namespace STD; cavltree: cavltree () {T = NULL;} cavltree ::~ Cavltree () {// If (t) // {// If (null = T-> left & null = T-> right) // Delete T; // else {// Delete T-> left; // Delete T-> right; //} deletetree (t );} // create the AVL Tree void cavltree: createavltree (elementtype * data, int N) {If (t) based on the data values of each element) {cout <"the AVL tree has been created" <Endl; return;} If (! N) // The element sequence is null {T = NULL; return ;}for (INT I = 0; I <n; ++ I) {T = insertnode (t, * (Data + I);} return;} avltree cavltree: insertnode (avltree T, elementtype Val) {avlnode * pnewnode = new avlnode; pnewnode-> element = val; pnewnode-> left = NULL; pnewnode-> right = NULL; pnewnode-> Height = 1; // The new node must be inserted into the null node if (null = T) {T = pnewnode; return t;} // The non-empty tree that needs to be inserted. // The inserted elements already exist in the tree, if (val = T-> element) {cout <"element already exists, build AVL Tree Failed! "<Endl; return t ;}// the value to be inserted is smaller than the value of the root node. insert it into the left subtree if (Val <t-> element) {// insert it into the left subtree of the root node T-> left = insertnode (t-> left, Val ); // determine whether the balance condition still meets if (getheight (t-> left)-getheight (t-> right)> 1) {// perform the rotation operation in two cases. // If (Val <t-> left-> element) // implement single rotation-Right rotation T = singlerightrotate (t); else // the insertion point is located in the right subtree of the Left subnode of T, implement dual-Right rotation T = doublerightrotate (t) ;}// the value to be inserted is greater than the value of the root node, insert it into the right subtree if (Val> T-> element) {T-> right = insertnode (t-> right, Val); // Determine whether the balance condition still meets if (getheight (t-> right)-getheight (t-> left)> 1) {// Insert the node to the right subtree of the right subnode of T if (Val> T-> right-> element) // implement single rotation-left rotation T = singleleftrotate (t ); else // Insert the node to the left subtree of the right subnode of T // implement double rotation-left rotation T = doubleleftrotate (t );}} // update the height value of the node setheight (T, max (getheight (t-> left), getheight (t-> right) + 1); Return t;} avltree cavltree:: deletenode (avltree T, const elementtype Val) {If (! T) {cout <"the tree is null, delete failed" <Endl; return t;} avltree searchednode = searchnode (T, Val ); // failed to delete if (! Searchednode) {cout <"cann't find the node to delete" <Val <Endl; return t ;} // locate the node to be deleted // The node to be deleted is the root node of the current subtree if (val = T-> element) {// left and right subtree are not empty if (t-> left & T-> right) {// Delete the child tree with a higher height if (getheight (t-> left)> getheight (t-> right) {// The height of the left child tree is large, delete the node with the largest element value in the left subtree and assign the value to the root node T-> element = getmaxnode (t-> left)-> element; t-> left = deletenode (t-> left, T-> element);} else {// Delete the node with the smallest element value in the right subtree, assign the value to the root node T-> element. = Getminnode (t-> right)-> element; t-> right = deletenode (t-> right, T-> element );}} else {// one of the left and right subtree is not empty. Replace it with the child node of the node to be deleted. Then avltree oldnode = T; t = (t-> left? T-> left: T-> right); Delete oldnode; // release the space occupied by the node oldnode = NULL;} else if (Val <t-> element) // The node to be deleted is in the left subtree {// recursively Delete T-> left = deletenode (t-> left, Val) in the left subtree ); // determine whether the balance condition is still met if (getheight (t-> right)-getheight (t-> left)> 1) {If (t-> right-> left> T-> right) {// left double rotation T = doubleleftrotate (t );} else // perform a single left rotation T = singleleftrotate (t);} else // meets the equilibrium condition, you need to update the height Information t-> Height = max (getheight (t-> left), getheight (t-> right) + 1 ;} Else // The node to be deleted is in the right subtree {T-> right = deletenode (t-> right, Val ); // determine whether the equilibrium condition is met. If (getheight (t-> left)-getheight (t-> right)> 1) {If (getheight (t-> left-> right)> getheight (t-> left) // right double rotation T = doublerightrotate (t ); else // right single rotation T = singlerightrotate (t);} else // you only need to adjust the height T-> Height = max (getheight (t-> left ), getheight (t-> right) + 1;} return t;} avltree cavltree: searchnode (avltree T, elementtype Val) {If (! T) {return NULL;} // you can find if (val = T-> element) {return t;} else if (Val <t-> element) {// search for return searchnode (t-> left, Val) in the left subtree;} else {// search for return searchnode (t-> right, val) ;}} void cavltree: Preorder (avltree t) {If (! T) cout <"null"; else {cout <t-> element <""; preorder (t-> left ); preorder (t-> right) ;}} avltree cavltree: getmaxnode (avltree t) {If (! T) // tree is empty {return NULL;} avltree tempnode = T; // search right until the right child node is nullwhile (tempnode-> right) {tempnode = tempnode-> right;} return tempnode;} avltree cavltree: getminnode (avltree t) {If (! T) // tree is empty {return NULL;} avltree tempnode = T; // search left until the left child node is nullwhile (tempnode-> left) {tempnode = tempnode-> left;} return tempnode;} int cavltree: getheight (avltree t) {return (t = NULL )? 0: (t-> height);} void cavltree: setheight (avltree T, int height) {T-> Height = height;} // imbalance caused by left outer insertion, correction by single rotation-Right rotation // parameter explanation: // T: pointing to the minimum subtree root node avltree cavltree: singlerightrotate (avltree t) that is out of balance due to an operation) {avltree xpnode = T; avltree ypnode = T-> left; xpnode-> left = ypnode-> right; // modify the left subtree ypnode-> right = xpnode of the original root node; // change the right subtree of the left child of the original root node // update the height of the node that has been rotated. xpnode-> Height = max (getheight (xpnode-> left ), getheight (xpnode-> right )) + 1; ypnode-> Height = max (getheight (ypnode-> left), getheight (ypnode-> right) + 1; // The left child node of the original root node becomes the new root node return ypnode;} // the imbalance caused by insertion of the right outer side is corrected by single rotation-left rotation. // parameter explanation: // T: pointing to avltree cavltree: singleleftrotate (avltree t) {avltree xpnode = T; avltree ypnode = T-> right; xpnode-> right = ypnode-> left; // change the right child ypnode of the original root node-> left = xpnode; // upgrade the right child node of the original root node to a new root node // update the height of the node that has been rotated. xpnode-> Height = max (getheight (xpnod E-> left), getheight (xpnode-> right) + 1; ypnode-> Height = max (getheight (ypnode-> left), getheight (ypnode-> right )) + 1; // return the New Root Node return ypnode;} // The right subtree avltree cavltree: doublerightrotate (avltree t) where the insertion point is located at the left subnode of T) {// double rotation can be achieved through two single rotations // The first single rotation assert (t-> left! = NULL); // perform a single rotation on the left subtree-left rotation T-> left = singleleftrotate (t-> left ); // The second single rotation // perform a single rotation on the newly generated tree-Right rotation return singlerightrotate (t );} // The left subtree avltree cavltree: doubleleftrotate (avltree t) where the insertion point is located at the right subnode of T) {// double rotation can be achieved through two single rotations // The first single rotation assert (t-> right! = NULL); // perform a single rotation on the right subtree-Right rotation T-> right = singlerightrotate (t-> right ); // The second single rotation // perform a single rotation on the newly generated tree-return singleleftrotate (t);} void cavltree: deletetree (avltree T) {If (null = T) return; deletetree (t-> left); deletetree (t-> right); Delete t; t = NULL ;}


Main. cpp:

// AVL tree-Adelson-Velskii-Landis tree programming implementation // Author: Jiangnan smoke rain // time: 2012-12-10 # include "AVLTree. h "# include <iostream> using namespace std; int main () {const int NumElements = 5; cout <" AVL Tree Operation Programming implementation: "<endl; int a [NumElements] = {18,14, 20,12, 16}; CAVLTree * CAVLTreeObj1 = new CAVLTree (); CAVLTreeObj1-> createAVLTree (a, NumElements ); cout <"AVL Tree first-order traversal result:" <endl; CAVLTreeObj1-> preOrder (CAVLTreeObj1-> T); cou T <endl; int insertedVal1 = 15; CAVLTreeObj1-> T = CAVLTreeObj1-> insertNode (CAVLTreeObj1-> T, insertedVal1 ); cout <"insert element to AVL Tree" <insertedVal1 <"result of first-order traversal:" <endl; CAVLTreeObj1-> preOrder (CAVLTreeObj1-> T ); cout <endl; int insertedval = 16; CAVLTreeObj1-> T = CAVLTreeObj1-> insertNode (CAVLTreeObj1-> T, insertedval ); cout <"insert element to AVL Tree" <insertedval <"result of first-order traversal:" <endl; CAVLTreeObj1-> preOrder (CAVLTreeObj1-> T); cout <endl; int minVal = CAVLTreeObj1-> getMinNode (CAVLTreeObj1-> T)-> element; the smallest element in the cout <"tree is: "<minVal <endl; int maxVal = CAVLTreeObj1-> getMaxNode (CAVLTreeObj1-> T)-> element; cout <" the maximum element in the tree is: "<maxVal <endl; const int deletedVal1 = 11; CAVLTreeObj1-> T = CAVLTreeObj1-> deleteNode (CAVLTreeObj1-> T, deletedVal1 ); result of first-order tree traversal after the cout <"delete element value is" <deletedVal1 <":" <endl; CAVLTr EeObj1-> preOrder (CAVLTreeObj1-> T); cout <endl; const int deletedVal2 = 20; region-> T = region-> deleteNode (CAVLTreeObj1-> T, deletedVal2 ); result of first-order tree traversal after the cout <"delete element value is" <deletedVal2 <":" <endl; response-> preOrder (CAVLTreeObj1-> T); cout <endl; const int deletedVal3 = 18; response-> T = CAVLTreeObj1-> deleteNode (CAVLTreeObj1-> T, deletedVal3 ); cout <"delete a node whose element value is" <deletedVal3 <" Result of the subsequent tree first traversal: "<endl; CAVLTreeObj1-> preOrder (CAVLTreeObj1-> T); cout <endl; const int searchedVal1 = 12; AVLTree searchedPNode = CAVLTreeObj1-> searchNode (CAVLTreeObj1-> T, searchedVal1); if (! SearchedPNode) cout <"cannot find such node whose elemen equals" <searchedVal1 <endl; elsecout <"search success element" <searchedVal1 <endl; const int searchedVal2 = 13; searchedPNode = CAVLTreeObj1-> searchNode (CAVLTreeObj1-> T, searchedVal2); if (! SearchedPNode) cout <"cannot find such node whose elemen equals" <searchedVal2 <endl; elsecout <"search success element" <searchedVal2 <endl; return 0 ;}

Running result (Win7 + VS2008 ):



The above Tree operations are illustrated as follows (mobile phone shooting is a bit unclear ):




Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.