384 lines
10 KiB
C++
384 lines
10 KiB
C++
#include "avl.h"
|
|
|
|
avl::avl(): root(NULL) {}
|
|
|
|
avl::~avl() {
|
|
deltree(root);
|
|
}
|
|
|
|
void avl::deltree (node* root) {
|
|
// if(root != NULL) {
|
|
// deltree(root->left);
|
|
// deltree(root->right);
|
|
// }
|
|
// delete root;
|
|
}
|
|
|
|
NodeInterface* avl::getRootNode() {
|
|
return root;
|
|
}
|
|
|
|
bool avl::add(int data) {
|
|
bool found = false;
|
|
node* current;
|
|
node* parent;
|
|
current = root;
|
|
while(current) {
|
|
if(current->data == data) {
|
|
found = true;
|
|
break;
|
|
}
|
|
else {
|
|
parent = current;
|
|
if(data > current->data) {
|
|
current = current->right;
|
|
}
|
|
else if(data < current->data) {
|
|
current = current->left;
|
|
}
|
|
}
|
|
}
|
|
if(found) {
|
|
return false;
|
|
}
|
|
root = build(root, data);
|
|
return true;
|
|
}
|
|
|
|
node* avl::build(node* root, int data) {
|
|
node* temp1 = NULL;
|
|
node* temp2 = NULL;
|
|
if(root == NULL) {
|
|
root = new node(data);
|
|
h = true;
|
|
return root;
|
|
}
|
|
if(data < root->data) {
|
|
root->left = build(root->left, data);
|
|
if(h) {
|
|
switch(root->height) {
|
|
case 1:
|
|
temp1 = root->left;
|
|
if(temp1->height == 1) {
|
|
root->left = temp1->right;
|
|
temp1->right = root;
|
|
root->height = 0;
|
|
root = temp1;
|
|
}
|
|
else {
|
|
temp2 = temp1->right;
|
|
temp1->right = temp2->left;
|
|
temp2->left = temp1;
|
|
root->left = temp2->right;
|
|
temp2->right = root;
|
|
if(temp2->height == 1) {
|
|
root->height = -1;
|
|
}
|
|
else {
|
|
root->height = 0;
|
|
}
|
|
if(temp2->height == -1) {
|
|
temp1->height = 1;
|
|
}
|
|
else {
|
|
temp1->height = 0;
|
|
}
|
|
root = temp2;
|
|
}
|
|
root->height = 0;
|
|
h = false;
|
|
break;
|
|
case 0:
|
|
root->height = 1;
|
|
break;
|
|
case -1:
|
|
root->height = 0;
|
|
h = false;
|
|
}
|
|
}
|
|
}
|
|
if(data > root->data) {
|
|
root->right = build(root->right, data);
|
|
if(h) {
|
|
switch(root->height) {
|
|
case 1:
|
|
root->height = 0;
|
|
h = false;
|
|
break;
|
|
case 0:
|
|
root->height = -1;
|
|
break;
|
|
case -1:
|
|
temp1 = root->right;
|
|
if(temp1->height == -1) {
|
|
root->right = temp1->left;
|
|
temp1->left = root;
|
|
root->height = 0;
|
|
root = temp1;
|
|
}
|
|
else {
|
|
temp2 = temp1->left;
|
|
temp1->left = temp2->right;
|
|
temp2->right = temp1;
|
|
root->right = temp2->left;
|
|
temp2->left = root;
|
|
if(temp2->height == -1) {
|
|
root->height = 1;
|
|
}
|
|
else {
|
|
root->height = 0;
|
|
}
|
|
if(temp2->height == 1) {
|
|
temp1->height = -1;
|
|
}
|
|
else {
|
|
temp1->height = 0;
|
|
}
|
|
root = temp2;
|
|
}
|
|
root->height = 0;
|
|
h = false;
|
|
}
|
|
}
|
|
}
|
|
return root;
|
|
}
|
|
|
|
bool avl::remove(int data) {
|
|
bool found = false;
|
|
if(root == NULL) {
|
|
return false;
|
|
}
|
|
node* current;
|
|
node* parent;
|
|
current = root;
|
|
while(current) {
|
|
if(current->data == data) {
|
|
found = true;
|
|
break;
|
|
}
|
|
else {
|
|
parent = current;
|
|
if(data > current->data) {
|
|
current = current->right;
|
|
}
|
|
else if(data < current->data) {
|
|
current = current->left;
|
|
}
|
|
}
|
|
}
|
|
if(!found) {
|
|
return false;
|
|
}
|
|
root = del_leaf(root, data);
|
|
return true;
|
|
}
|
|
|
|
node* avl::del_leaf(node* root, int data) {
|
|
node* temp;
|
|
if(root == NULL) {
|
|
return root;
|
|
}
|
|
else {
|
|
if(data < root->data) {
|
|
root->left = del_leaf(root->left, data);
|
|
if(h) {
|
|
root = bal_right(root);
|
|
}
|
|
}
|
|
else {
|
|
if(data > root->data) {
|
|
root->right = del_leaf(root->right, data);
|
|
if(h) {
|
|
root = bal_left(root);
|
|
}
|
|
}
|
|
else {
|
|
temp = root;
|
|
if(temp->right == NULL) {
|
|
root = temp->left;
|
|
h = true;
|
|
delete temp;
|
|
}
|
|
else {
|
|
if(temp->left == NULL) {
|
|
root = temp->right;
|
|
h = true;
|
|
delete temp;
|
|
}
|
|
else {
|
|
temp->left = del(temp->left, temp);
|
|
if(h) {
|
|
root = bal_right(root);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return root;
|
|
}
|
|
|
|
node* avl::del(node* succ, node* n) {
|
|
node* temp = succ;
|
|
if(succ->right != NULL) {
|
|
succ->right = del(succ->right, n);
|
|
if(h) {
|
|
succ = bal_left(succ);
|
|
}
|
|
}
|
|
else {
|
|
node* current;
|
|
node* parent;
|
|
current = root;
|
|
while(current) {
|
|
if(current->data == succ->data) {
|
|
break;
|
|
}
|
|
else {
|
|
parent = current;
|
|
if(succ->data > current->data) {
|
|
current = current->right;
|
|
}
|
|
else if(succ->data < current->data) {
|
|
current = current->left;
|
|
}
|
|
}
|
|
}
|
|
if(root->left->data == succ->data) {
|
|
root->data = succ->data;
|
|
n->right = root->right;
|
|
succ = succ->left;
|
|
delete temp;
|
|
h = true;
|
|
return succ;
|
|
}
|
|
else if(root->right->data == succ->data) {
|
|
root->data = succ->data;
|
|
n->right = root->right;
|
|
succ = succ->right;
|
|
delete temp;
|
|
h = false;
|
|
return succ;
|
|
}
|
|
temp = succ;
|
|
n->data = succ->data;
|
|
succ = succ->left;
|
|
delete temp;
|
|
h = true;
|
|
}
|
|
return succ;
|
|
}
|
|
|
|
node* avl::bal_right(node* root) {
|
|
node* temp1 = NULL;
|
|
node* temp2 = NULL;
|
|
switch(root->height) {
|
|
case 1:
|
|
root->height = 0;
|
|
break;
|
|
case 0:
|
|
root->height = -1;
|
|
h = false;
|
|
break;
|
|
case -1:
|
|
temp1 = root->right;
|
|
if(temp1->height <= 0) {
|
|
root->right = temp1->left;
|
|
temp1->left = root;
|
|
if(temp1->height == 0) {
|
|
root->height = -1;
|
|
temp1->height = 1;
|
|
h = false;
|
|
}
|
|
else {
|
|
root->height = 0;
|
|
temp1->height = 0;
|
|
}
|
|
root = temp1;
|
|
}
|
|
else {
|
|
temp2 = temp1->left;
|
|
temp1->left = temp2->right;
|
|
temp2->right = temp1;
|
|
root->right = temp2->left;
|
|
temp2->left = root;
|
|
if(temp2->height == -1) {
|
|
root->height = 1;
|
|
}
|
|
else {
|
|
root->height = 0;
|
|
}
|
|
if(temp2->height == 1) {
|
|
temp1->height = -1;
|
|
}
|
|
else {
|
|
temp1->height = 0;
|
|
}
|
|
root = temp2;
|
|
temp2->height = 0;
|
|
}
|
|
}
|
|
return root;
|
|
}
|
|
|
|
node* avl::bal_left(node* root) {
|
|
node* temp1 = NULL;
|
|
node* temp2 = NULL;
|
|
switch(root->height) {
|
|
case -1:
|
|
root->height = 0;
|
|
break;
|
|
case 0:
|
|
root->height = 1;
|
|
h = false;
|
|
break;
|
|
case 1:
|
|
temp1 = root->left;
|
|
if(temp1->height >= 0) {
|
|
root->left = temp1->right;
|
|
temp1->right = root;
|
|
if(temp1->height == 0) {
|
|
root->height = 1;
|
|
temp1->height = -1;
|
|
h = false;
|
|
}
|
|
else {
|
|
root->height = 0;
|
|
temp1->height = 0;
|
|
}
|
|
root = temp1;
|
|
}
|
|
else {
|
|
temp2 = temp1->right;
|
|
temp1->right = temp2->left;
|
|
temp2->left = temp1;
|
|
root->left = temp2->right;
|
|
temp2->right = root;
|
|
if(temp2->height == 1) {
|
|
root->height = -1;
|
|
}
|
|
else {
|
|
root->height = 0;
|
|
}
|
|
if(temp2->height == -1) {
|
|
temp1->height = 1;
|
|
}
|
|
else {
|
|
temp1->height = 0;
|
|
}
|
|
root = temp2;
|
|
temp2->height = 0;
|
|
}
|
|
}
|
|
return root;
|
|
}
|
|
|
|
void avl::display(node* root) {
|
|
if(root != NULL) {
|
|
display(root->left);
|
|
cout << root->data << "\t";
|
|
display(root->right);
|
|
}
|
|
}
|