501 lines
15 KiB
C++
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;
|
|
}
|