school/cs235/final/br_tree.cpp
2016-04-06 20:46:10 -07:00

501 lines
15 KiB
C++

#include "br_tree.h"
br_tree::br_tree():root(NULL), h(false){}
vector<string> parse_expression(string expression) { //parses expression with " " being the delimeter
vector<string> results;
string s;
for(unsigned int i = 0; i < expression.length(); i++) {
char c = expression[i];
if(c != ' ') {
s += c;
}
else {
if(s != "") {
results.push_back(s);
s.clear();
}
}
}
if(s != "") {
results.push_back(s);
}
return results;
}
bool br_tree::in_tree(string data) {
bool found = false;
br_node* current;
br_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;
}
}
}
return found;
}
RedBlackNodeInterface* br_tree::getRootNode() {
return root;
}
void br_tree::add(string word) {
if(in_tree(word)) {
return;
}
if(root == NULL) {
root = new br_node(word);
root->color = 1;
return;
}
br_node* current;
br_node* cur_parent;
current = root;
while(current) {
cur_parent = current;
if(word > current->data) {
current = current->right;
}
else {
current = current->left;
}
}
if(word < cur_parent->data) {
cur_parent->left = new br_node(word);
cur_parent->left->parent = cur_parent;
br_node* child_added = cur_parent->left;
if(cur_parent->color == 0 && child_added->color == 0) {
balance(cur_parent->left);
}
return;
}
else {
cur_parent->right = new br_node(word);
cur_parent->right->parent = cur_parent;
br_node* child_added = cur_parent->right;
if(cur_parent->color == 0 && child_added->color == 0) {
balance(cur_parent->right);
}
return;
}
}
void br_tree::balance(br_node* cur) {
if((cur->data == root->data) || (cur->parent->data == root->data)) {
return;
}
if((cur->parent->parent->right != NULL) && (cur->parent->parent->left != NULL)) {
if((cur->parent->parent->left->color == 0) && (cur->parent->parent->right->color == 0)) {
cur->parent->parent->left->color = 1;
cur->parent->parent->right->color = 1;
cur->parent->parent->color = 0;
balance(cur->parent->parent);
return;
}
}
if((cur->parent->color == 0) && (cur->color == 0)) {
if((cur->parent->left != NULL) && (cur->parent->parent->left != NULL)) {
if((cur->parent->left->data == cur->data) && (cur->parent->parent->left->data == cur->parent->data)) {
//case III left
br_node* temp = cur->parent->parent;
if(cur->parent->right == NULL) {
temp->left = cur->parent->right;
}
else {
temp->left = cur->parent->right;
cur->parent->right->parent = temp;
}
cur->parent->right = temp;
if(temp->parent != NULL) {
if(temp->parent->right->data == temp->data) {
temp->parent->right = cur->parent;
}
else {
temp->parent->left = cur->parent;
}
}
else {
root = cur->parent;
}
cur->parent->parent = temp->parent;
temp->parent = cur->parent;
cur->parent->color = 1;
temp->color = 0;
balance(cur->parent);
return;
}
}
if((cur->parent->left != NULL) && (cur->parent->parent->right != NULL)) {
if((cur->parent->left->data == cur->data) && (cur->parent->parent->right->data == cur->parent->data)){
//case II right
br_node* temp1 = cur->parent->parent;
br_node* temp2 = cur->parent;
if(cur->right == NULL) {
temp2->left = cur->right;
}
else {
temp2->left = cur->right;
cur->right->parent = temp2;
}
cur->right = temp2;
temp2->parent = cur;
cur->parent = temp1;
temp1->right = cur;
balance(temp2);
return;
}
}
if((cur->parent->right != NULL) && (cur->parent->parent->left != NULL)) {
if((cur->parent->right->data == cur->data) && (cur->parent->parent->left->data == cur->parent->data)){
//case II left
br_node* temp1 = cur->parent->parent;
br_node* temp2 = cur->parent;
if(cur->left == NULL) {
temp2->right = cur->left;
}
else {
temp2->right = cur->left;
cur->left->parent = temp2;
}
cur->left = temp2;
temp2->parent = cur;
cur->parent = temp1;
temp1->left = cur;
balance(temp2);
return;
}
}
if((cur->parent->right != NULL) && (cur->parent->parent->right != NULL)) {
if((cur->parent->right->data == cur->data) && (cur->parent->parent->right->data == cur->parent->data)) {
//case III right
br_node* temp = cur->parent->parent;
if(cur->parent->left == NULL) {
temp->right = cur->parent->left;
}
else {
temp->right = cur->parent->left;
cur->parent->left->parent = temp;
}
cur->parent->left = temp;
if(temp->parent != NULL) {
if(temp->parent->right->data == temp->data) {
temp->parent->right = cur->parent;
}
else {
temp->parent->left = cur->parent;
}
}
else {
root = cur->parent;
}
cur->parent->parent = temp->parent;
temp->parent = cur->parent;
cur->parent->color = 1;
temp->color = 0;
balance(cur->parent);
return;
}
}
}
if(root->color == 0) {
root->color = 1;
return;
}
balance(cur->parent);
}
void br_tree::addPhrase(string words) {
vector<string> parsed_string = parse_expression(words);
for(unsigned int i = 0; i < parsed_string.size(); i++) {
add(parsed_string[i]);
}
}
void br_tree::remove(string word) {
if(!(in_tree(word))) {
return;
}
if(root == NULL) {
return;
}
br_node* current;
br_node* parent;
current = root;
while(current) {
if(current->data == word) {
break;
}
else {
parent = current;
if(word > current->data) {
current = current->right;
}
else if(word < current->data) {
current = current->left;
}
}
}
if(current->color == 1) {
h = true;
}
else {
h = false;
}
root = del_leaf(root, word);
}
br_node* br_tree::del_leaf(br_node* root, string data) {
br_node* temp;
if(root == NULL) {
return root;
}
else {
if(data < root->data) {
root->left = del_leaf(root->left, data);
if(h) {
cout << "2" << endl;
bal_del(root->left);
}
}
else {
if(data > root->data) {
root->right = del_leaf(root->right, data);
if(h) {
cout << "3" << endl;
cout << root->data << endl;
bal_del(root->right);
}
}
else {
temp = root;
if(temp->right == NULL) {
root = temp->left;
delete temp;
}
else {
if(temp->left == NULL) {
root = temp->right;
delete temp;
}
else {
temp->left = del(temp->left, temp);
if(h) {
cout << "4" << endl;
if(h) {
bal_del(temp);
}
}
}
}
}
}
}
return root;
}
void br_tree::bal_del(br_node* x) {
//cout << "bal_del(" << x->data << ")" << endl;
if(x == NULL) {
return;
}
while(x != root && x->color == 1) {
if(x == x->parent->left) {
br_node* w = x->parent->right;
if(w == NULL) {
return;
}
if(w->right == NULL || w->left == NULL) {
return;
}
if(w != NULL && w->right != NULL && w->left != NULL) {
if(w->color == 0) {
cout << "case 1 first" << endl;
w->color = 1; //Case 1
x->parent->color = 0; //Case 1
left_rot(x->parent); //Case 1
w = x->parent->right; //Case 1
}
else if(w->left->color == 1 && w->right->color == 1) {
cout << "case 2 first" << endl;
w->color = 1; //Case 2
x = x->parent; //Case 2
}
else {
if(w->right->color == 1) {
cout << "case 3 first" << endl;
w->left->color = 1; //Case 3
w->color = 0; //Case 3
right_rot(w); //Case 3
w = x->parent->right; //Case 3
}
cout << "case 4 first" << endl;
w->color = x->parent->color; //Case 4
x->parent->color = 1; //Case 4
w->right->color = 1; //Case 4
left_rot(x->parent);
x = root;
}
}
}
else {
br_node* w = x->parent->left;
if(w == NULL) {
return;
}
if(w->right == NULL || w->left == NULL) {
return;
}
if(w->color == 0) {
cout << "case 1 second" << endl;
w->color = 1; //Case 1
x->parent->color = 0; //Case 1
right_rot(x->parent); //Case 1
w = x->parent->left; //Case 1
}
else if(w->right->color == 1 && w->left->color == 1) {
cout << "case 2 second" << endl;
w->color = 0; //Case 2
x = x->parent; //Case 2
}
else {
if(w->left->color == 1) {
cout << "case 3 second" << endl;
w->right->color = 1; //Case 3
w->color = 0; //Case 3
left_rot(w); //Case 3
w = x->parent->left; //Case 3
}
cout << "case 4 second" << endl;
w->color = x->parent->color; //Case 4
x->parent->color = 1; //Case 4
w->left->color = 1; //Case 4
right_rot(x->parent);
x = root;
}
}
}
x->color = 1;
}
br_node* br_tree::del(br_node* succ, br_node* n) {
br_node* temp = succ;
if(succ->right != NULL) {
succ->right = del(succ->right, n);
}
else {
br_node* current;
br_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;
return succ;
}
else if(root->right->data == succ->data) {
root->data = succ->data;
n->right = root->right;
succ = succ->right;
delete temp;
return succ;
}
temp = succ;
n->data = succ->data;
succ = succ->left;
delete temp;
}
return succ;
}
void br_tree::right_rot(br_node* x) {
br_node* y = x->left;
x->left = y->right;
if(y->right != NULL) {
y->right->parent = x;
}
y->parent = x->parent;
if(x->parent == NULL) {
root = y;
}
else if(x == x->parent->right) {
x->parent->right = y;
}
else {
x->parent->left = y;
}
y->right = x;
x->parent = y;
}
void br_tree::left_rot(br_node* x) {
br_node* y = x->right;
x->right = y->left;
if(y->left != NULL) {
y->left->parent = x;
}
y->parent = x->parent;
if(x->parent == NULL) {
root = y;
}
else if(x == x->parent->left) {
x->parent->left = y;
}
else {
x->parent->right = y;
}
y->left = x;
x->parent = y;
}
void br_tree::printer(br_node* node, int a) {
a++;
if(node == NULL) {
return;
}
printer(node->right, a);
for(int i = 0; i <= a; i++) {
cout << "\t";
}
printf("%s %d", node->data.c_str(), node->color);
cout << endl << endl;
printer(node->left, a);
}
string br_tree::printTree() {
string tree;
if(root == NULL) {
return "";
}
cout << root->data << endl;
cout << endl;
printer(root, 0);
cout << endl;
return tree;
}