adding cs235
This commit is contained in:
@@ -0,0 +1,31 @@
|
||||
CXXFLAGS= -Wall -g -std=c++0x
|
||||
OBJECTS=RedBlackTreeFactory.o br_tree.o br_node.o main.o
|
||||
EXE=main
|
||||
all: $(EXE)
|
||||
|
||||
$(EXE): $(OBJECTS)
|
||||
$(CXX) $(CXXFLAGS) $(OBJECTS) -o $@
|
||||
test: test.cpp RedBlackTreeFactory.o br_node.o
|
||||
rtest: test
|
||||
./test
|
||||
RedBlackTreeFactory.o: RedBlackTreeFactory.cpp RedBlackTreeFactory.h
|
||||
br_node.o: br_node.cpp br_node.h
|
||||
br_tree.o: br_tree.cpp br_tree.h
|
||||
main.o: main.cpp
|
||||
|
||||
run: main
|
||||
./main
|
||||
|
||||
clean:
|
||||
@rm -vf *.o
|
||||
@rm -vf $(EXE)
|
||||
@rm -vf *.1
|
||||
@rm -vf *.0
|
||||
@rm -vf test
|
||||
@rm -rvf *.dSYM
|
||||
|
||||
drun: main
|
||||
gdb ./main
|
||||
|
||||
valgrind: $(EXE)
|
||||
valgrind --tool=memcheck --leak-check=yes ./$(EXE)
|
||||
@@ -0,0 +1,43 @@
|
||||
//YOU MAY NOT MODIFY THIS DOCUMENT
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class RedBlackNodeInterface {
|
||||
|
||||
public:
|
||||
RedBlackNodeInterface() {}
|
||||
virtual ~RedBlackNodeInterface() {}
|
||||
|
||||
/*
|
||||
* Returns the word that is stored in this node
|
||||
*
|
||||
* @return the word that is stored in this node.
|
||||
*/
|
||||
virtual string getWord() = 0;
|
||||
|
||||
/*
|
||||
* Returns the color of the node. A red node should return 0
|
||||
* and a black node should return 1.
|
||||
*
|
||||
* @return the color of the node
|
||||
*/
|
||||
virtual int getColor() = 0;
|
||||
|
||||
/*
|
||||
* Returns the left child of this node or null if it doesn't have one.
|
||||
*
|
||||
* @return the left child of this node or null if it doesn't have one.
|
||||
*/
|
||||
virtual RedBlackNodeInterface * getLeftChild() = 0;
|
||||
|
||||
/*
|
||||
* Returns the right child of this node or null if it doesn't have one.
|
||||
*
|
||||
* @return the right child of this node or null if it doesn't have one.
|
||||
*/
|
||||
virtual RedBlackNodeInterface * getRightChild() = 0;
|
||||
|
||||
};
|
||||
@@ -0,0 +1,20 @@
|
||||
#include "RedBlackTreeFactory.h"
|
||||
#include "br_tree.h"
|
||||
//You may add #include statements here
|
||||
|
||||
/*
|
||||
You will MODIFY THIS DOCUMENT.
|
||||
*/
|
||||
//=======================================================================================
|
||||
/*
|
||||
getRedBlackTree()
|
||||
|
||||
Creates and returns an object whose class extends RedBlackTreeInterface.
|
||||
This should be an object of a class you have created.
|
||||
|
||||
Example: If you made a class called "RedBlackTree", you might say, "return new RedBlackTree();".
|
||||
*/
|
||||
RedBlackTreeInterface * RedBlackTreeFactory::getRedBlackTree()
|
||||
{
|
||||
return new br_tree();//Modify this line
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
#include "RedBlackTreeInterface.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
/*
|
||||
WARNING: It is expressly forbidden to modify any part of this document, including its name
|
||||
*/
|
||||
//=======================================================================================
|
||||
/*
|
||||
getRedBlackTree()
|
||||
|
||||
Creates and returns an object whose class extends RedBlackTreeInterface.
|
||||
This should be an object of a class you have created.
|
||||
|
||||
Example: If you made a class called "RedBlackTree", you might say, "return new RedBlackTree();".
|
||||
*/
|
||||
class RedBlackTreeFactory
|
||||
{
|
||||
public:
|
||||
static RedBlackTreeInterface * getRedBlackTree();
|
||||
};
|
||||
//=======================================================================================
|
||||
@@ -0,0 +1,78 @@
|
||||
//YOU MAY NOT MODIFY THIS DOCUMENT
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include "RedBlackNodeInterface.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
class RedBlackTreeInterface {
|
||||
public:
|
||||
RedBlackTreeInterface() {}
|
||||
virtual ~RedBlackTreeInterface() {}
|
||||
|
||||
//Please note that the class that implements this interface must be made
|
||||
//of objects which implement the NodeInterface
|
||||
|
||||
/*
|
||||
* Returns the root node for this tree
|
||||
*
|
||||
* @return the root node for this tree.
|
||||
*/
|
||||
virtual RedBlackNodeInterface * getRootNode() = 0;
|
||||
|
||||
/*
|
||||
* Attempts to add the given word to the tree
|
||||
*
|
||||
* Addition should be consistent with the instructions found in the exam instructions.
|
||||
*/
|
||||
virtual void add(string word) = 0;
|
||||
|
||||
/*
|
||||
* Attempts to add the given string of words to the tree
|
||||
*
|
||||
* A string of words consists of alphabetical characters, no punctuation marks,
|
||||
* and white space as the delimiter separating words. The string should be parsed and
|
||||
* each word should be added to the tree.
|
||||
*/
|
||||
virtual void addPhrase(string words) = 0;
|
||||
|
||||
/*
|
||||
* Attempts to remove the given word from the tree
|
||||
*
|
||||
* Removal should be consistent with the instructions found in the exam instructions.
|
||||
*/
|
||||
virtual void remove(string word) = 0;
|
||||
|
||||
/*
|
||||
* The tree should print in the following format:
|
||||
*
|
||||
* Root (value & color)
|
||||
* Left subtree root (value & color)
|
||||
* Left left subtree root (value & color)
|
||||
* Left right subtree root (value & color)
|
||||
* Right subtree root (value & color)
|
||||
* Right left subtree root (value & color)
|
||||
* Right right subtree root (value & color)
|
||||
*
|
||||
* For example:
|
||||
* The tree:
|
||||
*
|
||||
* jumps(b)
|
||||
* brown(r) quick(r)
|
||||
* The(b) fox(b) over(b) the(b)
|
||||
* lazy(r)
|
||||
*
|
||||
* Will print:
|
||||
* jumps(b)
|
||||
* brown(r)
|
||||
* The(b)
|
||||
* fox(b)
|
||||
* quick(r)
|
||||
* over(b)
|
||||
* lazy(r);
|
||||
* the(b)
|
||||
*
|
||||
*/
|
||||
virtual string printTree() = 0;
|
||||
};
|
||||
@@ -0,0 +1,21 @@
|
||||
#include "TwoThreeTreeFactory.h"
|
||||
//You may add #include statements here
|
||||
|
||||
/*
|
||||
You will MODIFY THIS DOCUMENT.
|
||||
*/
|
||||
//=======================================================================================
|
||||
/*
|
||||
getTwoThreeTree()
|
||||
|
||||
Creates and returns an object whose class extends TwoTreeTreeInterface.
|
||||
This should be an object of a class you have created.
|
||||
|
||||
Example: If you made a class called "TwoThreeTree", you might say, "return new TwoThreeTree();".
|
||||
|
||||
This method should return NULL or 0 if you do not intent to do the extra credit
|
||||
*/
|
||||
TwoThreeTreeInterface * TwoThreeTreeFactory::getTwoThreeTree()
|
||||
{
|
||||
return 0;//Modify this line
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
#include "TwoThreeTreeInterface.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
/*
|
||||
WARNING: It is expressly forbidden to modify any part of this document, including its name
|
||||
*/
|
||||
//=======================================================================================
|
||||
/*
|
||||
getTwoThreeTree()
|
||||
|
||||
Creates and returns an object whose class extends TwoThreeTreeInterface.
|
||||
This should be an object of a class you have created.
|
||||
|
||||
Example: If you made a class called "TwoThreeTree", you might say, "return new TwoThreeTree();".
|
||||
|
||||
This method should return NULL or 0 if you do not intent to do the extra credit
|
||||
*/
|
||||
class TwoThreeTreeFactory
|
||||
{
|
||||
public:
|
||||
static TwoThreeTreeInterface * getTwoThreeTree();
|
||||
};
|
||||
//=======================================================================================
|
||||
@@ -0,0 +1,58 @@
|
||||
//YOU MAY NOT MODIFY THIS DOCUMENT
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class TwoThreeTreeInterface {
|
||||
public:
|
||||
TwoThreeTreeInterface() {}
|
||||
virtual ~TwoThreeTreeInterface() {}
|
||||
|
||||
//This class may use a node of your own creation.
|
||||
|
||||
/*
|
||||
* Attempts to add the given word to the tree
|
||||
*
|
||||
* Addition should be consistent with the instructions found in the exam instructions.
|
||||
*/
|
||||
virtual void add(string word) = 0;
|
||||
|
||||
/*
|
||||
* Attempts to add the given string of words to the tree
|
||||
*
|
||||
* A string of words consists of alphabetical characters, no punctuation marks,
|
||||
* and white space as the delimiter separating words. The string should be parsed and
|
||||
* each word should be added to the tree.
|
||||
*/
|
||||
virtual void addPhrase(string words) = 0;
|
||||
|
||||
/*
|
||||
* Attempts to remove the given word from the tree
|
||||
*
|
||||
* Removal should be consistent with the instructions found in the exam instructions.
|
||||
*/
|
||||
virtual void remove(string word) = 0;
|
||||
|
||||
/*
|
||||
* The tree should print in the following format:
|
||||
*
|
||||
* Root (value)
|
||||
* Left subtree root (value)
|
||||
* Left left subtree root (value)
|
||||
* Left middle subtree root (value)
|
||||
* Left right subtree root (value)
|
||||
* Middle subtree root (value)
|
||||
* Middle left subtree root (value)
|
||||
* Middle middle subtree root (value)
|
||||
* Middle right subtree root (value)
|
||||
*
|
||||
* Right subtree root (value)
|
||||
* Right left subtree root (value)
|
||||
* Right middle subtree root (value)
|
||||
* Right right subtree root (value)
|
||||
*
|
||||
*/
|
||||
virtual string printTree() = 0;
|
||||
};
|
||||
@@ -0,0 +1,19 @@
|
||||
#include "br_node.h"
|
||||
|
||||
br_node::br_node(string data): data(data), color(0), parent(NULL), left(NULL), right(NULL) {}
|
||||
|
||||
string br_node::getWord() {
|
||||
return data;
|
||||
}
|
||||
|
||||
int br_node::getColor() {
|
||||
return color;
|
||||
}
|
||||
|
||||
RedBlackNodeInterface* br_node::getLeftChild() {
|
||||
return left;
|
||||
}
|
||||
|
||||
RedBlackNodeInterface* br_node::getRightChild() {
|
||||
return right;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
#ifndef __BR_NODE_H__
|
||||
#define __BR_NODE_H__
|
||||
|
||||
#include "RedBlackNodeInterface.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
class br_node : public RedBlackNodeInterface {
|
||||
public:
|
||||
br_node(string data);
|
||||
string data;
|
||||
int color; //red = 0, black = 1
|
||||
br_node* parent;
|
||||
br_node* left;
|
||||
br_node* right;
|
||||
string getWord();
|
||||
int getColor();
|
||||
RedBlackNodeInterface * getLeftChild();
|
||||
RedBlackNodeInterface * getRightChild();
|
||||
};
|
||||
#endif
|
||||
@@ -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;
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
#ifndef __BR_TREE_H__
|
||||
#define __BR_TREE_H__
|
||||
|
||||
#include "br_node.h"
|
||||
#include "RedBlackTreeInterface.h"
|
||||
#include <cstdio>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class br_tree : public RedBlackTreeInterface {
|
||||
public:
|
||||
br_tree();
|
||||
br_node* root;
|
||||
bool h;
|
||||
RedBlackNodeInterface * getRootNode();
|
||||
bool in_tree(string data);
|
||||
void add(string word);
|
||||
void addPhrase(string words);
|
||||
void remove(string word);
|
||||
void balance(br_node* cur);
|
||||
void transfer(br_node* temp1, br_node* temp2);
|
||||
void bal_del(br_node* x);
|
||||
br_node* del_leaf(br_node* root, string data);
|
||||
void right_rot(br_node* x);
|
||||
void left_rot(br_node* x);
|
||||
void printer(br_node* node, int a);
|
||||
br_node* del(br_node* succ, br_node* n);
|
||||
br_node* min(br_node* temp);
|
||||
string printTree();
|
||||
};
|
||||
#endif
|
||||
@@ -0,0 +1,235 @@
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <time.h>
|
||||
#include <stdlib.h>
|
||||
#include "RedBlackTreeFactory.h"
|
||||
#include "TwoThreeTreeFactory.h"
|
||||
#include "br_tree.h"
|
||||
|
||||
/* This main is provided to help you test your code. Be aware that the TAs will use a separate
|
||||
* test driver that will only test your red black tree code. You may modify this code if you wish,
|
||||
* but do not try to modify the main to get your own code to work.
|
||||
*/
|
||||
|
||||
|
||||
using namespace std;
|
||||
int getOption(int max, int min);
|
||||
string getString();
|
||||
void exitPause();
|
||||
|
||||
RedBlackTreeInterface * redBlackTree;
|
||||
TwoThreeTreeInterface * twoThreeTree;
|
||||
|
||||
int main()
|
||||
{
|
||||
srand(time(NULL));
|
||||
br_tree b;
|
||||
redBlackTree = RedBlackTreeFactory::getRedBlackTree();
|
||||
|
||||
if(redBlackTree == NULL) {
|
||||
cout << endl;
|
||||
cout << "Factory getRedBlackTree() returned NULL!\nExiting Test Driver (press enter to exit)" << endl;
|
||||
|
||||
exitPause();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// twoThreeTree = TwoThreeTreeFactory::getTwoThreeTree();
|
||||
|
||||
cout << "Final Exam Beginning" << endl;
|
||||
while(1)
|
||||
{
|
||||
int choice = 0;
|
||||
if(twoThreeTree == NULL) {
|
||||
cout<< "Please select an option:"
|
||||
<< "\n1. Add a single word to the tree"
|
||||
<< "\n2. Add a list of words to the tree"
|
||||
<< "\n3. Remove a single word from the tree"
|
||||
<< "\n4. Print the tree"
|
||||
<< "\n5. Quit Program" << endl;
|
||||
choice = getOption(1,5);
|
||||
}
|
||||
else {
|
||||
cout<< "Please select an option:"
|
||||
<< "\n1. Add a single word to the red black tree"
|
||||
<< "\n2. Add a list of words to the red black tree"
|
||||
<< "\n3. Remove a single word from the red black tree"
|
||||
<< "\n4. Print the red black tree"
|
||||
<< "\n5. Add a single word to the two three tree"
|
||||
<< "\n6. Add a list of words to the two three tree"
|
||||
<< "\n7. Remove a single word from the two three tree"
|
||||
<< "\n8. Print the two three tree"
|
||||
<< "\n9. Quit Program" << endl;
|
||||
choice = getOption(1,9);
|
||||
}
|
||||
if(choice == 1)
|
||||
{
|
||||
//Insert the string that the user passes to the program into the tree
|
||||
for(int i = 0; i < 50000; i++) {
|
||||
stringstream s;
|
||||
int rand_n = rand() % 50000;
|
||||
s << rand_n;
|
||||
b.add(s.str());
|
||||
}
|
||||
cout << b.root << endl;
|
||||
//cout<< "Enter the word to add to the tree (alphabetical characters, no punctuation marks, no spaces)."<<endl;
|
||||
//string insertToTree;
|
||||
//insertToTree = getString();
|
||||
//redBlackTree->add(insertToTree);
|
||||
}
|
||||
else if(choice == 2)
|
||||
{
|
||||
//Insert the string that the user passes to the program into the tree
|
||||
cout<< "Enter the string to add to the tree."
|
||||
<< "\n(alphabetical characters, no punctuation marks, and with white space as the delimiter separating words)" << endl;
|
||||
string insertToTree;
|
||||
insertToTree = getString();
|
||||
redBlackTree->addPhrase(insertToTree);
|
||||
}
|
||||
else if(choice == 3)
|
||||
{
|
||||
cout << "here" << endl;
|
||||
while(b.root) {
|
||||
cout << "ah" << endl;
|
||||
stringstream s;
|
||||
int rand_n = rand() % 50000;
|
||||
s << rand_n;
|
||||
b.remove(s.str());
|
||||
}
|
||||
//Remove the string that the user passes to the program into the tree
|
||||
//cout << "Enter the word to remove from the tree (alphabetical characters, no punctuation marks, no spaces)."<<endl;
|
||||
//string removeFromTree;
|
||||
//removeFromTree = getString();
|
||||
//redBlackTree->remove(removeFromTree);
|
||||
}
|
||||
else if(choice == 4)
|
||||
{
|
||||
cout << b.printTree();
|
||||
//cout << "Your tree:" << endl;
|
||||
//cout << "\t" << redBlackTree->printTree() << endl;
|
||||
}
|
||||
else if(choice == 5 && twoThreeTree == NULL)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else if(choice == 5 && twoThreeTree != NULL)
|
||||
{
|
||||
//Insert the string that the user passes to the program into the tree
|
||||
cout<< "Enter the word to add to the tree (alphabetical characters, no punctuation marks, no spaces)."<<endl;
|
||||
string insertToTree;
|
||||
insertToTree = getString();
|
||||
twoThreeTree->add(insertToTree);
|
||||
}
|
||||
else if(choice == 6)
|
||||
{
|
||||
//Insert the string that the user passes to the program into the tree
|
||||
cout<< "Enter the string to add to the tree."
|
||||
<< "\n(alphabetical characters, no punctuation marks, and with white space as the delimiter separating words)" << endl;
|
||||
string insertToTree;
|
||||
insertToTree = getString();
|
||||
twoThreeTree->addPhrase(insertToTree);
|
||||
}
|
||||
else if(choice == 7)
|
||||
{
|
||||
//Remove the string that the user passes to the program into the tree
|
||||
cout << "Enter the word to remove from the tree (alphabetical characters, no punctuation marks, no spaces)."<<endl;
|
||||
string removeFromTree;
|
||||
removeFromTree = getString();
|
||||
twoThreeTree->remove(removeFromTree);
|
||||
}
|
||||
else if(choice == 8)
|
||||
{
|
||||
cout << "Your tree:" << endl;
|
||||
cout << "\t" << twoThreeTree->printTree() << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
cout << "Thanks for Playing!" << endl;
|
||||
|
||||
exitPause();
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
int getOption(int min, int max)
|
||||
{
|
||||
int input = 0;
|
||||
bool done = false;
|
||||
while(!done)
|
||||
{
|
||||
input = 0;
|
||||
cin >> input;
|
||||
cin.ignore(1000,'\n');
|
||||
if(cin.fail())
|
||||
{
|
||||
cin.clear();
|
||||
cin.ignore(1000,'\n');
|
||||
cout << "Error: Invalid" << endl;
|
||||
}
|
||||
else if(input < min || input > max)
|
||||
{
|
||||
cout << "Error: Invalid number" << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
return input;
|
||||
}
|
||||
|
||||
string getString()
|
||||
{
|
||||
string input = "";
|
||||
bool done = false;
|
||||
while(!done)
|
||||
{
|
||||
input = "";
|
||||
getline(cin, input);
|
||||
if(cin.fail())
|
||||
{
|
||||
cin.clear();
|
||||
cin.ignore(1000,'\n');
|
||||
cout << "Error: Invalid name" << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
return input;
|
||||
}
|
||||
|
||||
string getWord()
|
||||
{
|
||||
string input = "";
|
||||
bool done = false;
|
||||
while(!done)
|
||||
{
|
||||
input = "";
|
||||
getline(cin, input);
|
||||
if(cin.fail())
|
||||
{
|
||||
cin.clear();
|
||||
cin.ignore(1000,'\n');
|
||||
cout << "Error: Invalid name" << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
return input;
|
||||
}
|
||||
|
||||
void exitPause() {
|
||||
#ifdef ON_WINDOWS
|
||||
system("pause");
|
||||
#else
|
||||
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
#include "br_tree.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
int main() {
|
||||
br_tree b;
|
||||
}
|
||||
Reference in New Issue
Block a user