chore(CPlusPlus): add avl tree (#323)
* chore(CPlusPlus): add in-order predecessor and successor for bst Delete in-order-Predecessor-and-successor.cpp * Update tree structure in comments update tree structure in comments to match the one which is being constructed * chore(CPlusPlus): add avl tree * Fix bugs * update readme * Update avl.cpp * Update avl.cpp * Update avl.cpp Co-authored-by: Arsenic <54987647+Arsenic-ATG@users.noreply.github.com>pull/330/head
parent
8fe868369b
commit
4e1b8a502a
|
@ -66,6 +66,7 @@
|
|||
5. [Binary Search Tree](Trees/binary-search-tree.cpp)
|
||||
6. [In order morris traversal](Trees/in-order-morris-traversal.cpp)
|
||||
7. [In order Predecessor and Successor](Trees/in-order-predecessor-and-successor.cpp)
|
||||
8. [Avl Tree](Trees/avl.cpp)
|
||||
|
||||
# Maths
|
||||
1. [Kaprekar Number](Maths/Kaprekar-number.cpp)
|
||||
|
|
|
@ -0,0 +1,182 @@
|
|||
/*
|
||||
* Avl tree's are self-balancing binary search tree such that
|
||||
* the balance factor of each node will be -1 or 0 or 1.
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
|
||||
struct TreeNode{
|
||||
TreeNode* left;
|
||||
TreeNode* right;
|
||||
int data, height;
|
||||
TreeNode(const int& data): data(data), left(nullptr), right(nullptr), height(0){}
|
||||
};
|
||||
|
||||
int height(TreeNode* node){
|
||||
//Return the height of the node
|
||||
|
||||
if(node == nullptr){ return -1; }
|
||||
return node->height;
|
||||
}
|
||||
|
||||
void updateheight(TreeNode*& node){
|
||||
//Update the height of the node
|
||||
|
||||
if(node == nullptr){ return; }
|
||||
node->height = 1 + std::max(height(node->left), height(node->right));
|
||||
}
|
||||
|
||||
int balance_factor(TreeNode* node){
|
||||
//Find the balance factor of the given node
|
||||
|
||||
if(node != nullptr){ return height(node->right) - height(node->left); }
|
||||
return 0;
|
||||
}
|
||||
|
||||
void leftrotation(TreeNode*& node){
|
||||
//Rotate the sub-tree rooted with the node to left
|
||||
|
||||
if(node == nullptr){ return; }
|
||||
|
||||
TreeNode* a = node;
|
||||
TreeNode* b = node->right;
|
||||
|
||||
a->right = b->left;
|
||||
b->left = a;
|
||||
node = b;
|
||||
|
||||
updateheight(a);
|
||||
updateheight(b);
|
||||
}
|
||||
|
||||
void rightrotation(TreeNode*& node){
|
||||
//Rotate the sub-tree rooted with the node to right
|
||||
|
||||
if(node == nullptr){ return; }
|
||||
|
||||
TreeNode* a = node;
|
||||
TreeNode* b = node->left;
|
||||
|
||||
a->left = b->right;
|
||||
b->right= a;
|
||||
node = b;
|
||||
|
||||
updateheight(a);
|
||||
updateheight(b);
|
||||
}
|
||||
|
||||
void right_leftrotation(TreeNode*& node){
|
||||
//Rotate the sub-tree rooted with the node to the right and then left
|
||||
|
||||
if(node == nullptr){ return; }
|
||||
|
||||
rightrotation(node->right);
|
||||
leftrotation(node);
|
||||
}
|
||||
|
||||
void left_rightrotation(TreeNode*& node){
|
||||
//Rotate the sub-tree rooted with the node to the left and then right
|
||||
|
||||
if(node == nullptr){ return; }
|
||||
|
||||
leftrotation(node->left);
|
||||
rightrotation(node);
|
||||
}
|
||||
|
||||
void insert(TreeNode*& root, const int& data){
|
||||
/*
|
||||
* Create and insert the node in the appropriate place of the tree
|
||||
* Update the height of every node in the tree
|
||||
* Check the balance factor of the node and do the appropriate rotation
|
||||
* To make the tree balanced
|
||||
*/
|
||||
|
||||
if(root == nullptr) {
|
||||
root = new TreeNode(data);
|
||||
}
|
||||
else if(root->data < data){ insert(root->right, data); }
|
||||
else{ insert(root->left, data); }
|
||||
|
||||
updateheight(root);
|
||||
|
||||
const int initial_bal = balance_factor(root) ;
|
||||
|
||||
if(initial_bal == 2){
|
||||
int r_bal = balance_factor(root->right);
|
||||
if(r_bal == 1 || r_bal == 0){ leftrotation(root); }
|
||||
else if(r_bal == -1){ right_leftrotation(root); }
|
||||
}
|
||||
else if(initial_bal == -2){
|
||||
int l_bal = balance_factor(root->left);
|
||||
if(l_bal == 1 || l_bal == 0){ left_rightrotation(root); }
|
||||
else if(l_bal == -1){ rightrotation(root); }
|
||||
}
|
||||
}
|
||||
|
||||
void print(TreeNode* root){
|
||||
if(root != nullptr){
|
||||
std::cout << root->data << " ";
|
||||
print(root->left);
|
||||
print(root->right);
|
||||
}
|
||||
}
|
||||
|
||||
int main(){
|
||||
TreeNode* root = nullptr;
|
||||
insert(root, 1);
|
||||
insert(root, 2);
|
||||
insert(root, 3);
|
||||
insert(root, 4);
|
||||
insert(root, 5);
|
||||
insert(root, 6);
|
||||
insert(root, 7);
|
||||
insert(root, 8);
|
||||
insert(root, 9);
|
||||
insert(root, 10);
|
||||
|
||||
/*
|
||||
|
||||
Binary tree
|
||||
1
|
||||
\
|
||||
2
|
||||
\
|
||||
3
|
||||
\
|
||||
4
|
||||
\
|
||||
5
|
||||
\
|
||||
6
|
||||
\
|
||||
7
|
||||
\
|
||||
8
|
||||
\
|
||||
9
|
||||
\
|
||||
10
|
||||
|
||||
Output: 1 2 3 4 5 6 7 8 9 10
|
||||
Here the balance factor of the root node is 9
|
||||
|
||||
Average case Time complexity for insert and remove: O(log(n))
|
||||
Worst cose Time complexity for insert and remove: O(n)
|
||||
|
||||
AVL Tree
|
||||
4
|
||||
/ \
|
||||
2 8
|
||||
/\ / \
|
||||
1 3 6 9
|
||||
/ \ \
|
||||
5 7 10
|
||||
|
||||
Output: 4 2 1 3 8 6 5 7 9 10
|
||||
Here the balance factor of the root node is 1
|
||||
|
||||
Average and worst case time complexity for insert and remove: O(log(n))
|
||||
*/
|
||||
|
||||
print(root);
|
||||
}
|
Loading…
Reference in New Issue