#include "br_tree.h" br_tree::br_tree():root(NULL), h(false){} vector parse_expression(string expression) { //parses expression with " " being the delimeter vector 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 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; }