27. AVL Trees(Self-balancing binary search tree)
19 Jun 2020 | Algorithm
Drawback Binary Search Tree
Introduction to AVL Trees
LL and RR Rotation on AVL
#include <iostream>
using namespace std;
class Node {
public:
Node* lchild;
int data;
Node* rchild;
int height;
};
class AVL{
public:
Node* root;
AVL(){ root = nullptr; }
// Helper methods for inserting
int NodeHeight(Node* p);
int BalanceFactor(Node* p);
Node* LLRotation(Node* p);
Node* RRRotation(Node* p);
Node* LRRotation(Node* p);
Node* RLRotation(Node* p);
// Insert
Node* rInsert(Node* p, int key);
// Traversal
void Inorder(Node* p);
void Inorder(){ Inorder(root); }
Node* getRoot(){ return root; }
};
int AVL::NodeHeight(Node *p) {
int hl;
int hr;
hl = (p && p->lchild) ? p->lchild->height : 0;
hr = (p && p->rchild) ? p->rchild->height : 0;
return hl > hr ? hl + 1 : hr + 1;
}
int AVL::BalanceFactor(Node *p) {
int hl;
int hr;
hl = (p && p->lchild) ? p->lchild->height : 0;
hr = (p && p->rchild) ? p->rchild->height : 0;
return hl - hr;
}
Node* AVL::LLRotation(Node *p) {
Node* pl = p->lchild;
Node* plr = pl->rchild;
pl->rchild = p;
p->lchild = plr;
// Update height
p->height = NodeHeight(p);
pl->height = NodeHeight(pl);
// Update root
if (root == p){
root = pl;
}
return pl;
}
Node* AVL::RRRotation(Node *p) {
Node* pr = p->rchild;
Node* prl = pr->lchild;
pr->lchild = p;
p->rchild = prl;
// Update height
p->height = NodeHeight(p);
pr->height = NodeHeight(pr);
// Update root
if (root == p){
root = pr;
}
return pr;
}
Node* AVL::LRRotation(Node *p) {
return nullptr;
}
Node* AVL::RLRotation(Node *p) {
return nullptr;
}
Node* AVL::rInsert(Node *p, int key) {
Node* t;
if (p == nullptr){
t = new Node;
t->data = key;
t->lchild = nullptr;
t->rchild = nullptr;
t->height = 1; // Starting height from 1 onwards instead of 0
return t;
}
if (key < p->data){
p->lchild = rInsert(p->lchild, key);
} else if (key > p->data){
p->rchild = rInsert(p->rchild, key);
}
// Update height
p->height = NodeHeight(p);
// Balance Factor and Rotation
if (BalanceFactor(p) == 2 && BalanceFactor(p->lchild) == 1) {
return LLRotation(p);
} else if (BalanceFactor(p) == 2 && BalanceFactor(p->lchild) == -1){
return LRRotation(p);
} else if (BalanceFactor(p) == -2 && BalanceFactor(p->rchild) == -1){
return RRRotation(p);
} else if (BalanceFactor(p) == -2 && BalanceFactor(p->rchild) == 1){
return RLRotation(p);
}
return p;
}
void AVL::Inorder(Node *p) {
if (p){
Inorder(p->lchild);
cout << p->data << ", " << flush;
Inorder(p->rchild);
}
}
int main() {
// LL Rotation
AVL tll;
tll.root = tll.rInsert(tll.root, 30);
tll.root = tll.rInsert(tll.root, 20);
tll.root = tll.rInsert(tll.root, 10);
tll.Inorder();
cout << endl;
// RR Rotation
AVL trr;
trr.root = trr.rInsert(trr.root, 10);
trr.root = trr.rInsert(trr.root, 20);
trr.root = trr.rInsert(trr.root, 30);
trr.Inorder();
cout << endl;
return 0;
}
LR and RL Rotation on AVL
#include <iostream>
using namespace std;
class Node {
public:
Node* lchild;
int data;
Node* rchild;
int height;
};
class AVL{
public:
Node* root;
AVL(){ root = nullptr; }
// Helper methods for inserting
int NodeHeight(Node* p);
int BalanceFactor(Node* p);
Node* LLRotation(Node* p);
Node* RRRotation(Node* p);
Node* LRRotation(Node* p);
Node* RLRotation(Node* p);
// Insert
Node* rInsert(Node* p, int key);
// Traversal
void Inorder(Node* p);
void Inorder(){ Inorder(root); }
Node* getRoot(){ return root; }
};
int AVL::NodeHeight(Node *p) {
int hl;
int hr;
hl = (p && p->lchild) ? p->lchild->height : 0;
hr = (p && p->rchild) ? p->rchild->height : 0;
return hl > hr ? hl + 1 : hr + 1;
}
int AVL::BalanceFactor(Node *p) {
int hl;
int hr;
hl = (p && p->lchild) ? p->lchild->height : 0;
hr = (p && p->rchild) ? p->rchild->height : 0;
return hl - hr;
}
Node* AVL::LLRotation(Node *p) {
Node* pl = p->lchild;
Node* plr = pl->rchild;
pl->rchild = p;
p->lchild = plr;
// Update height
p->height = NodeHeight(p);
pl->height = NodeHeight(pl);
// Update root
if (root == p){
root = pl;
}
return pl;
}
Node* AVL::RRRotation(Node *p) {
Node* pr = p->rchild;
Node* prl = pr->lchild;
pr->lchild = p;
p->rchild = prl;
// Update height
p->height = NodeHeight(p);
pr->height = NodeHeight(pr);
// Update root
if (root == p){
root = pr;
}
return pr;
}
Node* AVL::LRRotation(Node *p) {
Node* pl = p->lchild;
Node* plr = pl->rchild;
pl->rchild = plr->lchild;
p->lchild = plr->rchild;
plr->lchild = pl;
plr->rchild = p;
// Update height
pl->height = NodeHeight(pl);
p->height = NodeHeight(p);
plr->height = NodeHeight(plr);
// Update root
if (p == root){
root = plr;
}
return plr;
}
Node* AVL::RLRotation(Node *p) {
Node* pr = p->rchild;
Node* prl = pr->lchild;
pr->lchild = prl->rchild;
p->rchild =prl->lchild;
prl->rchild = pr;
prl->lchild = p;
// Update height
pr->height = NodeHeight(pr);
p->height = NodeHeight(p);
prl->height = NodeHeight(prl);
// Update root
if (root == p){
root = prl;
}
return prl;
}
Node* AVL::rInsert(Node *p, int key) {
Node* t;
if (p == nullptr){
t = new Node;
t->data = key;
t->lchild = nullptr;
t->rchild = nullptr;
t->height = 1; // Starting height from 1 onwards instead of 0
return t;
}
if (key < p->data){
p->lchild = rInsert(p->lchild, key);
} else if (key > p->data){
p->rchild = rInsert(p->rchild, key);
}
// Update height
p->height = NodeHeight(p);
// Balance Factor and Rotation
if (BalanceFactor(p) == 2 && BalanceFactor(p->lchild) == 1) {
return LLRotation(p);
} else if (BalanceFactor(p) == 2 && BalanceFactor(p->lchild) == -1){
return LRRotation(p);
} else if (BalanceFactor(p) == -2 && BalanceFactor(p->rchild) == -1){
return RRRotation(p);
} else if (BalanceFactor(p) == -2 && BalanceFactor(p->rchild) == 1){
return RLRotation(p);
}
return p;
}
void AVL::Inorder(Node *p) {
if (p){
Inorder(p->lchild);
cout << p->data << ", " << flush;
Inorder(p->rchild);
}
}
int main() {
// LR Rotation
AVL tll;
tll.root = tll.rInsert(tll.root, 50);
tll.root = tll.rInsert(tll.root, 10);
tll.root = tll.rInsert(tll.root, 20);
tll.Inorder();
cout << endl;
// RL Rotation
AVL trr;
trr.root = trr.rInsert(trr.root, 20);
trr.root = trr.rInsert(trr.root, 50);
trr.root = trr.rInsert(trr.root, 30);
trr.Inorder();
cout << endl;
return 0;
}
Deletion From AVL tree with Rotations
#include <iostream>
using namespace std;
class Node {
public:
Node* lchild;
int data;
Node* rchild;
int height;
};
class AVL{
public:
Node* root;
AVL(){ root = nullptr; }
// Helper methods for inserting/deleting
int NodeHeight(Node* p);
int BalanceFactor(Node* p);
Node* LLRotation(Node* p);
Node* RRRotation(Node* p);
Node* LRRotation(Node* p);
Node* RLRotation(Node* p);
Node* InPre(Node* p);
Node* InSucc(Node* p);
// Insert
Node* rInsert(Node* p, int key);
// Traversal
void Inorder(Node* p);
void Inorder(){ Inorder(root); }
Node* getRoot(){ return root; }
// Delete
Node* Delete(Node* p, int key);
};
int AVL::NodeHeight(Node *p) {
int hl;
int hr;
hl = (p && p->lchild) ? p->lchild->height : 0;
hr = (p && p->rchild) ? p->rchild->height : 0;
return hl > hr ? hl + 1 : hr + 1;
}
int AVL::BalanceFactor(Node *p) {
int hl;
int hr;
hl = (p && p->lchild) ? p->lchild->height : 0;
hr = (p && p->rchild) ? p->rchild->height : 0;
return hl - hr;
}
Node* AVL::LLRotation(Node *p) {
Node* pl = p->lchild;
Node* plr = pl->rchild;
pl->rchild = p;
p->lchild = plr;
// Update height
p->height = NodeHeight(p);
pl->height = NodeHeight(pl);
// Update root
if (root == p){
root = pl;
}
return pl;
}
Node* AVL::RRRotation(Node *p) {
Node* pr = p->rchild;
Node* prl = pr->lchild;
pr->lchild = p;
p->rchild = prl;
// Update height
p->height = NodeHeight(p);
pr->height = NodeHeight(pr);
// Update root
if (root == p){
root = pr;
}
return pr;
}
Node* AVL::LRRotation(Node *p) {
Node* pl = p->lchild;
Node* plr = pl->rchild;
pl->rchild = plr->lchild;
p->lchild = plr->rchild;
plr->lchild = pl;
plr->rchild = p;
// Update height
pl->height = NodeHeight(pl);
p->height = NodeHeight(p);
plr->height = NodeHeight(plr);
// Update root
if (p == root){
root = plr;
}
return plr;
}
Node* AVL::RLRotation(Node *p) {
Node* pr = p->rchild;
Node* prl = pr->lchild;
pr->lchild = prl->rchild;
p->rchild = prl->lchild;
prl->rchild = pr;
prl->lchild = p;
// Update height
pr->height = NodeHeight(pr);
p->height = NodeHeight(p);
prl->height = NodeHeight(prl);
// Update root
if (root == p){
root = prl;
}
return prl;
}
Node* AVL::InPre(Node *p) {
while (p && p->rchild != nullptr){
p = p->rchild;
}
return p;
}
Node* AVL::InSucc(Node *p) {
while (p && p->lchild != nullptr){
p = p->lchild;
}
return p;
}
Node* AVL::rInsert(Node *p, int key) {
Node* t;
if (p == nullptr){
t = new Node;
t->data = key;
t->lchild = nullptr;
t->rchild = nullptr;
t->height = 1; // Starting height from 1 onwards instead of 0
return t;
}
if (key < p->data){
p->lchild = rInsert(p->lchild, key);
} else if (key > p->data){
p->rchild = rInsert(p->rchild, key);
}
// Update height
p->height = NodeHeight(p);
// Balance Factor and Rotation
if (BalanceFactor(p) == 2 && BalanceFactor(p->lchild) == 1) {
return LLRotation(p);
} else if (BalanceFactor(p) == 2 && BalanceFactor(p->lchild) == -1){
return LRRotation(p);
} else if (BalanceFactor(p) == -2 && BalanceFactor(p->rchild) == -1){
return RRRotation(p);
} else if (BalanceFactor(p) == -2 && BalanceFactor(p->rchild) == 1){
return RLRotation(p);
}
return p;
}
void AVL::Inorder(Node *p) {
if (p){
Inorder(p->lchild);
cout << p->data << ", " << flush;
Inorder(p->rchild);
}
}
Node* AVL::Delete(Node *p, int key) {
if (p == nullptr){
return nullptr;
}
if (p->lchild == nullptr && p->rchild == nullptr){
if (p == root){
root = nullptr;
}
delete p;
return nullptr;
}
if (key < p->data){
p->lchild = Delete(p->lchild, key);
} else if (key > p->data){
p->rchild = Delete(p->rchild, key);
} else {
Node* q;
if (NodeHeight(p->lchild) > NodeHeight(p->rchild)){
q = InPre(p->lchild);
p->data = q->data;
p->lchild = Delete(p->lchild, q->data);
} else {
q = InSucc(p->rchild);
p->data = q->data;
p->rchild = Delete(p->rchild, q->data);
}
}
// Update height
p->height = NodeHeight(p);
// Balance Factor and Rotation
if (BalanceFactor(p) == 2 && BalanceFactor(p->lchild) == 1) { // L1 Rotation
return LLRotation(p);
} else if (BalanceFactor(p) == 2 && BalanceFactor(p->lchild) == -1){ // L-1 Rotation
return LRRotation(p);
} else if (BalanceFactor(p) == -2 && BalanceFactor(p->rchild) == -1){ // R-1 Rotation
return RRRotation(p);
} else if (BalanceFactor(p) == -2 && BalanceFactor(p->rchild) == 1){ // R1 Rotation
return RLRotation(p);
} else if (BalanceFactor(p) == 2 && BalanceFactor(p->lchild) == 0){ // L0 Rotation
return LLRotation(p);
} else if (BalanceFactor(p) == -2 && BalanceFactor(p->rchild) == 0){ // R0 Rotation
return RRRotation(p);
}
return p;
}
int main() {
AVL tree;
int A[] = {10, 20, 30, 25, 28, 27, 5};
for (int i=0; i<sizeof(A)/sizeof(A[0]); i++){
tree.root = tree.rInsert(tree.root, A[i]);
}
tree.Inorder();
cout << endl;
tree.Delete(tree.root, 28);
tree.Inorder();
cout << endl;
return 0;
}
Drawback Binary Search Tree
Introduction to AVL Trees
LL and RR Rotation on AVL
#include <iostream>
using namespace std;
class Node {
public:
Node* lchild;
int data;
Node* rchild;
int height;
};
class AVL{
public:
Node* root;
AVL(){ root = nullptr; }
// Helper methods for inserting
int NodeHeight(Node* p);
int BalanceFactor(Node* p);
Node* LLRotation(Node* p);
Node* RRRotation(Node* p);
Node* LRRotation(Node* p);
Node* RLRotation(Node* p);
// Insert
Node* rInsert(Node* p, int key);
// Traversal
void Inorder(Node* p);
void Inorder(){ Inorder(root); }
Node* getRoot(){ return root; }
};
int AVL::NodeHeight(Node *p) {
int hl;
int hr;
hl = (p && p->lchild) ? p->lchild->height : 0;
hr = (p && p->rchild) ? p->rchild->height : 0;
return hl > hr ? hl + 1 : hr + 1;
}
int AVL::BalanceFactor(Node *p) {
int hl;
int hr;
hl = (p && p->lchild) ? p->lchild->height : 0;
hr = (p && p->rchild) ? p->rchild->height : 0;
return hl - hr;
}
Node* AVL::LLRotation(Node *p) {
Node* pl = p->lchild;
Node* plr = pl->rchild;
pl->rchild = p;
p->lchild = plr;
// Update height
p->height = NodeHeight(p);
pl->height = NodeHeight(pl);
// Update root
if (root == p){
root = pl;
}
return pl;
}
Node* AVL::RRRotation(Node *p) {
Node* pr = p->rchild;
Node* prl = pr->lchild;
pr->lchild = p;
p->rchild = prl;
// Update height
p->height = NodeHeight(p);
pr->height = NodeHeight(pr);
// Update root
if (root == p){
root = pr;
}
return pr;
}
Node* AVL::LRRotation(Node *p) {
return nullptr;
}
Node* AVL::RLRotation(Node *p) {
return nullptr;
}
Node* AVL::rInsert(Node *p, int key) {
Node* t;
if (p == nullptr){
t = new Node;
t->data = key;
t->lchild = nullptr;
t->rchild = nullptr;
t->height = 1; // Starting height from 1 onwards instead of 0
return t;
}
if (key < p->data){
p->lchild = rInsert(p->lchild, key);
} else if (key > p->data){
p->rchild = rInsert(p->rchild, key);
}
// Update height
p->height = NodeHeight(p);
// Balance Factor and Rotation
if (BalanceFactor(p) == 2 && BalanceFactor(p->lchild) == 1) {
return LLRotation(p);
} else if (BalanceFactor(p) == 2 && BalanceFactor(p->lchild) == -1){
return LRRotation(p);
} else if (BalanceFactor(p) == -2 && BalanceFactor(p->rchild) == -1){
return RRRotation(p);
} else if (BalanceFactor(p) == -2 && BalanceFactor(p->rchild) == 1){
return RLRotation(p);
}
return p;
}
void AVL::Inorder(Node *p) {
if (p){
Inorder(p->lchild);
cout << p->data << ", " << flush;
Inorder(p->rchild);
}
}
int main() {
// LL Rotation
AVL tll;
tll.root = tll.rInsert(tll.root, 30);
tll.root = tll.rInsert(tll.root, 20);
tll.root = tll.rInsert(tll.root, 10);
tll.Inorder();
cout << endl;
// RR Rotation
AVL trr;
trr.root = trr.rInsert(trr.root, 10);
trr.root = trr.rInsert(trr.root, 20);
trr.root = trr.rInsert(trr.root, 30);
trr.Inorder();
cout << endl;
return 0;
}
LR and RL Rotation on AVL
#include <iostream>
using namespace std;
class Node {
public:
Node* lchild;
int data;
Node* rchild;
int height;
};
class AVL{
public:
Node* root;
AVL(){ root = nullptr; }
// Helper methods for inserting
int NodeHeight(Node* p);
int BalanceFactor(Node* p);
Node* LLRotation(Node* p);
Node* RRRotation(Node* p);
Node* LRRotation(Node* p);
Node* RLRotation(Node* p);
// Insert
Node* rInsert(Node* p, int key);
// Traversal
void Inorder(Node* p);
void Inorder(){ Inorder(root); }
Node* getRoot(){ return root; }
};
int AVL::NodeHeight(Node *p) {
int hl;
int hr;
hl = (p && p->lchild) ? p->lchild->height : 0;
hr = (p && p->rchild) ? p->rchild->height : 0;
return hl > hr ? hl + 1 : hr + 1;
}
int AVL::BalanceFactor(Node *p) {
int hl;
int hr;
hl = (p && p->lchild) ? p->lchild->height : 0;
hr = (p && p->rchild) ? p->rchild->height : 0;
return hl - hr;
}
Node* AVL::LLRotation(Node *p) {
Node* pl = p->lchild;
Node* plr = pl->rchild;
pl->rchild = p;
p->lchild = plr;
// Update height
p->height = NodeHeight(p);
pl->height = NodeHeight(pl);
// Update root
if (root == p){
root = pl;
}
return pl;
}
Node* AVL::RRRotation(Node *p) {
Node* pr = p->rchild;
Node* prl = pr->lchild;
pr->lchild = p;
p->rchild = prl;
// Update height
p->height = NodeHeight(p);
pr->height = NodeHeight(pr);
// Update root
if (root == p){
root = pr;
}
return pr;
}
Node* AVL::LRRotation(Node *p) {
Node* pl = p->lchild;
Node* plr = pl->rchild;
pl->rchild = plr->lchild;
p->lchild = plr->rchild;
plr->lchild = pl;
plr->rchild = p;
// Update height
pl->height = NodeHeight(pl);
p->height = NodeHeight(p);
plr->height = NodeHeight(plr);
// Update root
if (p == root){
root = plr;
}
return plr;
}
Node* AVL::RLRotation(Node *p) {
Node* pr = p->rchild;
Node* prl = pr->lchild;
pr->lchild = prl->rchild;
p->rchild =prl->lchild;
prl->rchild = pr;
prl->lchild = p;
// Update height
pr->height = NodeHeight(pr);
p->height = NodeHeight(p);
prl->height = NodeHeight(prl);
// Update root
if (root == p){
root = prl;
}
return prl;
}
Node* AVL::rInsert(Node *p, int key) {
Node* t;
if (p == nullptr){
t = new Node;
t->data = key;
t->lchild = nullptr;
t->rchild = nullptr;
t->height = 1; // Starting height from 1 onwards instead of 0
return t;
}
if (key < p->data){
p->lchild = rInsert(p->lchild, key);
} else if (key > p->data){
p->rchild = rInsert(p->rchild, key);
}
// Update height
p->height = NodeHeight(p);
// Balance Factor and Rotation
if (BalanceFactor(p) == 2 && BalanceFactor(p->lchild) == 1) {
return LLRotation(p);
} else if (BalanceFactor(p) == 2 && BalanceFactor(p->lchild) == -1){
return LRRotation(p);
} else if (BalanceFactor(p) == -2 && BalanceFactor(p->rchild) == -1){
return RRRotation(p);
} else if (BalanceFactor(p) == -2 && BalanceFactor(p->rchild) == 1){
return RLRotation(p);
}
return p;
}
void AVL::Inorder(Node *p) {
if (p){
Inorder(p->lchild);
cout << p->data << ", " << flush;
Inorder(p->rchild);
}
}
int main() {
// LR Rotation
AVL tll;
tll.root = tll.rInsert(tll.root, 50);
tll.root = tll.rInsert(tll.root, 10);
tll.root = tll.rInsert(tll.root, 20);
tll.Inorder();
cout << endl;
// RL Rotation
AVL trr;
trr.root = trr.rInsert(trr.root, 20);
trr.root = trr.rInsert(trr.root, 50);
trr.root = trr.rInsert(trr.root, 30);
trr.Inorder();
cout << endl;
return 0;
}
Deletion From AVL tree with Rotations
#include <iostream>
using namespace std;
class Node {
public:
Node* lchild;
int data;
Node* rchild;
int height;
};
class AVL{
public:
Node* root;
AVL(){ root = nullptr; }
// Helper methods for inserting/deleting
int NodeHeight(Node* p);
int BalanceFactor(Node* p);
Node* LLRotation(Node* p);
Node* RRRotation(Node* p);
Node* LRRotation(Node* p);
Node* RLRotation(Node* p);
Node* InPre(Node* p);
Node* InSucc(Node* p);
// Insert
Node* rInsert(Node* p, int key);
// Traversal
void Inorder(Node* p);
void Inorder(){ Inorder(root); }
Node* getRoot(){ return root; }
// Delete
Node* Delete(Node* p, int key);
};
int AVL::NodeHeight(Node *p) {
int hl;
int hr;
hl = (p && p->lchild) ? p->lchild->height : 0;
hr = (p && p->rchild) ? p->rchild->height : 0;
return hl > hr ? hl + 1 : hr + 1;
}
int AVL::BalanceFactor(Node *p) {
int hl;
int hr;
hl = (p && p->lchild) ? p->lchild->height : 0;
hr = (p && p->rchild) ? p->rchild->height : 0;
return hl - hr;
}
Node* AVL::LLRotation(Node *p) {
Node* pl = p->lchild;
Node* plr = pl->rchild;
pl->rchild = p;
p->lchild = plr;
// Update height
p->height = NodeHeight(p);
pl->height = NodeHeight(pl);
// Update root
if (root == p){
root = pl;
}
return pl;
}
Node* AVL::RRRotation(Node *p) {
Node* pr = p->rchild;
Node* prl = pr->lchild;
pr->lchild = p;
p->rchild = prl;
// Update height
p->height = NodeHeight(p);
pr->height = NodeHeight(pr);
// Update root
if (root == p){
root = pr;
}
return pr;
}
Node* AVL::LRRotation(Node *p) {
Node* pl = p->lchild;
Node* plr = pl->rchild;
pl->rchild = plr->lchild;
p->lchild = plr->rchild;
plr->lchild = pl;
plr->rchild = p;
// Update height
pl->height = NodeHeight(pl);
p->height = NodeHeight(p);
plr->height = NodeHeight(plr);
// Update root
if (p == root){
root = plr;
}
return plr;
}
Node* AVL::RLRotation(Node *p) {
Node* pr = p->rchild;
Node* prl = pr->lchild;
pr->lchild = prl->rchild;
p->rchild = prl->lchild;
prl->rchild = pr;
prl->lchild = p;
// Update height
pr->height = NodeHeight(pr);
p->height = NodeHeight(p);
prl->height = NodeHeight(prl);
// Update root
if (root == p){
root = prl;
}
return prl;
}
Node* AVL::InPre(Node *p) {
while (p && p->rchild != nullptr){
p = p->rchild;
}
return p;
}
Node* AVL::InSucc(Node *p) {
while (p && p->lchild != nullptr){
p = p->lchild;
}
return p;
}
Node* AVL::rInsert(Node *p, int key) {
Node* t;
if (p == nullptr){
t = new Node;
t->data = key;
t->lchild = nullptr;
t->rchild = nullptr;
t->height = 1; // Starting height from 1 onwards instead of 0
return t;
}
if (key < p->data){
p->lchild = rInsert(p->lchild, key);
} else if (key > p->data){
p->rchild = rInsert(p->rchild, key);
}
// Update height
p->height = NodeHeight(p);
// Balance Factor and Rotation
if (BalanceFactor(p) == 2 && BalanceFactor(p->lchild) == 1) {
return LLRotation(p);
} else if (BalanceFactor(p) == 2 && BalanceFactor(p->lchild) == -1){
return LRRotation(p);
} else if (BalanceFactor(p) == -2 && BalanceFactor(p->rchild) == -1){
return RRRotation(p);
} else if (BalanceFactor(p) == -2 && BalanceFactor(p->rchild) == 1){
return RLRotation(p);
}
return p;
}
void AVL::Inorder(Node *p) {
if (p){
Inorder(p->lchild);
cout << p->data << ", " << flush;
Inorder(p->rchild);
}
}
Node* AVL::Delete(Node *p, int key) {
if (p == nullptr){
return nullptr;
}
if (p->lchild == nullptr && p->rchild == nullptr){
if (p == root){
root = nullptr;
}
delete p;
return nullptr;
}
if (key < p->data){
p->lchild = Delete(p->lchild, key);
} else if (key > p->data){
p->rchild = Delete(p->rchild, key);
} else {
Node* q;
if (NodeHeight(p->lchild) > NodeHeight(p->rchild)){
q = InPre(p->lchild);
p->data = q->data;
p->lchild = Delete(p->lchild, q->data);
} else {
q = InSucc(p->rchild);
p->data = q->data;
p->rchild = Delete(p->rchild, q->data);
}
}
// Update height
p->height = NodeHeight(p);
// Balance Factor and Rotation
if (BalanceFactor(p) == 2 && BalanceFactor(p->lchild) == 1) { // L1 Rotation
return LLRotation(p);
} else if (BalanceFactor(p) == 2 && BalanceFactor(p->lchild) == -1){ // L-1 Rotation
return LRRotation(p);
} else if (BalanceFactor(p) == -2 && BalanceFactor(p->rchild) == -1){ // R-1 Rotation
return RRRotation(p);
} else if (BalanceFactor(p) == -2 && BalanceFactor(p->rchild) == 1){ // R1 Rotation
return RLRotation(p);
} else if (BalanceFactor(p) == 2 && BalanceFactor(p->lchild) == 0){ // L0 Rotation
return LLRotation(p);
} else if (BalanceFactor(p) == -2 && BalanceFactor(p->rchild) == 0){ // R0 Rotation
return RRRotation(p);
}
return p;
}
int main() {
AVL tree;
int A[] = {10, 20, 30, 25, 28, 27, 5};
for (int i=0; i<sizeof(A)/sizeof(A[0]); i++){
tree.root = tree.rInsert(tree.root, A[i]);
}
tree.Inorder();
cout << endl;
tree.Delete(tree.root, 28);
tree.Inorder();
cout << endl;
return 0;
}
Comments