school/cs235/lab10/avl.cpp

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);
}
}