The following source codes are used in this chapter.
AVL trees
1. Main function using AVLtree class
// Data Structure & Algorithm C++, Otgonbayar Tovuudorj
// Chapter 13: Balanced trees
// AVL: Demonstration program for AVL trees;
// insertion and deletion of nodes
#include "avl_tree.h"
int main() {
int x;
char ch;
AVLtree<int> t;
cout <<
"\nAVL tree displayed by this program has\n"
"its root on the left. Turn it 90 degrees\n"
"clockwise to obtain its usual representation.\n\n";
for ( ; ; ) {
cout <<
"Enter an integer, then I for insertion\n"
"or by D for deletion, or enter Q to quit: ";
cin >> x >> ch;
if (cin.fail()) break;
ch = toupper(ch);
if (ch == 'I') t.insert(t.getroot(),x); else
if (ch == 'D') t.delNode(t.getroot(),x);
t.print(t.getroot());
}
return 0;
}
2. Header file: avl_tree.h
// Data Structure & Algorithm C++, Otgonbayar Tovuudorj
// Chapter 13: Balanced trees
// AVL: Demonstration program for AVL trees;
// insertion and deletion of nodes
// File name: avl_tree.h
#include <iostream>
#include <iomanip>
using namespace std;
template <class Type>
class AVLtree {
struct Node {
Type data;
int bf;
Node *l, *r;
};
Node *root;
void rrRotate(Node* &p);
void llRotate(Node* &p);
public:
AVLtree():root(NULL){}
Node *&getroot() { return root; }
int insert(Node* &p, Type x);
int delNode(Node* &p, Type x);
void print(Node *p, int ws = 0);
};
template <class Type>
void AVLtree<Type>::rrRotate(Node* &p) {
Node *q = p;
p = p->r;
q->r = p->l;
p->l = q;
q->bf--;
if (p->bf > 0) q->bf -= p->bf;
p->bf--;
if (q->bf < 0) p->bf += q->bf;
}
template <class Type>
void AVLtree<Type>::llRotate(Node* &p) {
Node *q = p;
p = p->l;
q->l = p->r;
p->r = q;
q->bf++;
if (p->bf < 0) q->bf -= p->bf;
p->bf++;
if (q->bf > 0) p->bf += q->bf;
}
template <class Type>
int AVLtree<Type>::insert(Node* &p, Type x) {
int dh=0;
if (p == NULL) {
p = new Node;
p->data = x; p->bf = 0;
p->l = p->r = NULL;
dh = 1; // Tree height increased by 1
} else
if (x > p->data) {
if (insert(p->r, x)) {
p->bf++; // Height of right subtree increased
if (p->bf == 1) dh = 1; else
if (p->bf == 2) {
if (p->r->bf == -1) llRotate(p->r);
rrRotate(p);
}
}
} else
if (x < p->data) {
if (insert(p->l, x)) {
p->bf--; // Height of left subtree increased
if (p->bf == -1) dh = 1; else
if (p->bf == -2) {
if (p->l->bf == 1) rrRotate(p->l);
llRotate(p);
}
}
}
return dh;
}
template <class Type>
int AVLtree<Type>::delNode(Node* &p, Type x) {
Node **qq, *p0;
int dh=0;
if (p == NULL) return 0;
if (x < p->data) {
if (delNode(p->l, x)) {
p->bf++; // Height left subtree decreased
if (p->bf == 0) dh = 1; else
if (p->bf == 2) {
if (p->r->bf == -1) llRotate(p->r);
rrRotate(p);
if (p->bf == 0) dh = 1;
}
}
} else
if (x > p->data) {
if (delNode(p->r, x)) {
p->bf--; // Height right subtree decreased
if (p->bf == 0) dh = 1; else
if (p->bf == -2) {
if (p->l->bf == 1) rrRotate(p->l);
llRotate(p);
if (p->bf == 0) dh = 1;
}
}
} else { // x == p->data
if (p->r == NULL) {
p0 = p; p = p->l; delete p0; return 1;
} else
if (p->l == NULL) {
p0 = p; p = p->r; delete p0; return 1;
} else {
qq = & p->l;
while ((*qq)->r != NULL) qq = & (*qq)->r;
p->data = (*qq)->data;
(*qq)->data = x;
if (delNode(p->l, x)) {
p->bf++; // Height left subtree decreased
if (p->bf == 0) dh = 1; else
if (p->bf == 2) {
if (p->r->bf == -1) llRotate(p->r);
rrRotate(p);
if (p->bf == 0) dh = 1;
}
}
}
}
return dh;
}
template <class Type>
void AVLtree<Type>::print(Node *p, int ws) {
if (p != NULL) {
print(p->r, ws+=6);
cout << setw(ws) << p->data << " " << p->bf << endl;
print(p->l, ws);
}
}
AVL trees using Friend class
1. Main function using AVLtree class
// Data Structure & Algorithm C++, Otgonbayar Tovuudorj
// Chapter 13: Balanced trees
// AVL: Demonstration program for AVL trees;
// insertion and deletion of nodes
// using friend class
#include "avl_tree_fc.h"
int main() {
int x;
char ch;
AVLtree<int> t;
cout <<
"\nAVL tree displayed by this program has\n"
"its root on the left. Turn it 90 degrees\n"
"clockwise to obtain its usual representation.\n\n";
for ( ; ; ) {
cout <<
"Enter an integer, then I for insertion\n"
"or by D for deletion, or enter Q to quit: ";
cin >> x >> ch;
if (cin.fail()) break;
ch = toupper(ch);
if (ch == 'I') t.insert(t.getroot(),x); else
if (ch == 'D') t.delNode(t.getroot(),x);
t.print(t.getroot());
}
return 0;
}
2. Header file: avl_tree_fc.h
// Data Structure & Algorithm C++, Otgonbayar Tovuudorj
// Chapter 13: Balanced trees
// AVL: Demonstration program for AVL trees;
// insertion and deletion of nodes
// using friend class
// File name : avl_tree_fc.h
#include <iostream>
#include <iomanip>
using namespace std;
template <class Type>
class Node {
template <class> friend class AVLtree;
Type data;
int bf;
Node *l, *r;
};
template <class Type>
class AVLtree {
Node<Type> *root;
void rrRotate(Node<Type>* &p);
void llRotate(Node<Type>* &p);
public:
AVLtree():root(NULL){}
Node<Type> *&getroot() { return root; }
int insert(Node<Type>* &p, Type x);
int delNode(Node<Type>* &p, Type x);
void print(Node<Type> *p, int ws = 0);
};
template <class Type>
void AVLtree<Type>::rrRotate(Node<Type>* &p) {
Node<Type> *q = p;
p = p->r;
q->r = p->l;
p->l = q;
q->bf--;
if (p->bf > 0) q->bf -= p->bf;
p->bf--;
if (q->bf < 0) p->bf += q->bf;
}
template <class Type>
void AVLtree<Type>::llRotate(Node<Type>* &p) {
Node<Type> *q = p;
p = p->l;
q->l = p->r;
p->r = q;
q->bf++;
if (p->bf < 0) q->bf -= p->bf;
p->bf++;
if (q->bf > 0) p->bf += q->bf;
}
template <class Type>
int AVLtree<Type>::insert(Node<Type>* &p, Type x) {
int dh=0;
if (p == NULL) {
p = new Node<Type>;
p->data = x; p->bf = 0;
p->l = p->r = NULL;
dh = 1; // Tree height increased by 1
} else
if (x > p->data) {
if (insert(p->r, x)) {
p->bf++; // Height of right subtree increased
if (p->bf == 1) dh = 1; else
if (p->bf == 2) {
if (p->r->bf == -1) llRotate(p->r);
rrRotate(p);
}
}
} else
if (x < p->data) {
if (insert(p->l, x)) {
p->bf--; // Height of left subtree increased
if (p->bf == -1) dh = 1; else
if (p->bf == -2) {
if (p->l->bf == 1) rrRotate(p->l);
llRotate(p);
}
}
}
return dh;
}
template <class Type>
int AVLtree<Type>::delNode(Node<Type>* &p, Type x) {
Node<Type> **qq, *p0;
int dh=0;
if (p == NULL) return 0;
if (x < p->data) {
if (delNode(p->l, x)) {
p->bf++; // Height left subtree decreased
if (p->bf == 0) dh = 1; else
if (p->bf == 2) {
if (p->r->bf == -1) llRotate(p->r);
rrRotate(p);
if (p->bf == 0) dh = 1;
}
}
} else
if (x > p->data) {
if (delNode(p->r, x)) {
p->bf--; // Height right subtree decreased
if (p->bf == 0) dh = 1; else
if (p->bf == -2) {
if (p->l->bf == 1) rrRotate(p->l);
llRotate(p);
if (p->bf == 0) dh = 1;
}
}
} else { // x == p->data
if (p->r == NULL) {
p0 = p; p = p->l; delete p0; return 1;
} else
if (p->l == NULL) {
p0 = p; p = p->r; delete p0; return 1;
} else {
qq = & p->l;
while ((*qq)->r != NULL) qq = & (*qq)->r;
p->data = (*qq)->data;
(*qq)->data = x;
if (delNode(p->l, x)) {
p->bf++; // Height left subtree decreased
if (p->bf == 0) dh = 1; else
if (p->bf == 2) {
if (p->r->bf == -1) llRotate(p->r);
rrRotate(p);
if (p->bf == 0) dh = 1;
}
}
}
}
return dh;
}
template <class Type>
void AVLtree<Type>::print(Node<Type> *p, int ws) {
if (p != NULL) {
print(p->r, ws+=6);
cout << setw(ws) << p->data << " " << p->bf << endl;
print(p->l, ws);
}
}
