adding cs235
This commit is contained in:
@@ -0,0 +1,500 @@
|
||||
#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;
|
||||
}
|
||||
Reference in New Issue
Block a user