Trimmed working portion to slowly implement instead
This commit is contained in:
parent
8370fa19f1
commit
cbdc502193
@ -56,7 +56,7 @@ namespace tree_implementation
|
||||
virtual void PrintPathToRoot(std::string key) = 0;
|
||||
private:
|
||||
TreeNode* Insert(std::unique_ptr<TreeNode> root, std::unique_ptr<TreeNode> newNode);
|
||||
TreeNode* Search(std::unique_ptr<TreeNode> viewedNode, std::string wordToFind);
|
||||
TreeNode* Search(std::unique_ptr<TreeNode>* viewedNode, std::string wordToFind);
|
||||
};
|
||||
|
||||
// Binary Search Tree operations
|
||||
|
266
src/trees.cpp
266
src/trees.cpp
@ -51,108 +51,108 @@ namespace tree_implementation
|
||||
// Inserts a node into a BST
|
||||
void TreeInterface::Insert(std::unique_ptr<TreeNode> z)
|
||||
{
|
||||
std::unique_ptr<TreeNode> y(nullptr);
|
||||
std::unique_ptr<TreeNode> x(tree.head.release());
|
||||
while (x)
|
||||
{
|
||||
y = x.release();
|
||||
if (z->key < x->key)
|
||||
x = x->leftChild.release();
|
||||
else
|
||||
x = x->rightChild.release();
|
||||
}
|
||||
z->parent = y.release();
|
||||
if (!y)
|
||||
tree.head = z.release();
|
||||
else if (z->key < y->key)
|
||||
y->leftChild = z.release();
|
||||
else
|
||||
y->rightChild = z.release();
|
||||
// std::unique_ptr<TreeNode> y(nullptr);
|
||||
// std::unique_ptr<TreeNode> x(tree.head.release());
|
||||
// while (x)
|
||||
// {
|
||||
// y = x.release();
|
||||
// if (z->key < x->key)
|
||||
// x = x->leftChild.release();
|
||||
// else
|
||||
// x = x->rightChild.release();
|
||||
// }
|
||||
// z->parent = y.release();
|
||||
// if (!y)
|
||||
// tree.head = z.release();
|
||||
// else if (z->key < y->key)
|
||||
// y->leftChild = z.release();
|
||||
// else
|
||||
// y->rightChild = z.release();
|
||||
return;
|
||||
}
|
||||
|
||||
// Searches for the given word in a tree
|
||||
TreeNode* TreeInterface::Search(std::string wordToFind)
|
||||
{
|
||||
return _Search(tree.head, wordToFind);
|
||||
return Search(&tree.head, wordToFind);
|
||||
}
|
||||
|
||||
bool IsSearchSuccessful(std::unique_ptr<TreeNode> foundNode)
|
||||
bool TreeInterface::IsSearchSuccessful(std::unique_ptr<TreeNode> foundNode)
|
||||
{
|
||||
if (foundNode)
|
||||
return true;
|
||||
std::cout << "No node found with key '" << foundNode->key << "'\n";
|
||||
// if (foundNode)
|
||||
// return true;
|
||||
// std::cout << "No node found with key '" << foundNode->key << "'\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Prints tree while traversing it
|
||||
void TreeInterface::InOrderTreeTraversal(std::unique_ptr<TreeNode> viewedNode)
|
||||
{
|
||||
if (viewedNode)
|
||||
InOrderTreeTraversal(viewedNode->leftChild);
|
||||
std::cout << viewedNode.key << '\n';
|
||||
InOrderTreeTraversal(viewedNode->rightChild);
|
||||
// if (viewedNode)
|
||||
// InOrderTreeTraversal(viewedNode->leftChild);
|
||||
// std::cout << viewedNode.key << '\n';
|
||||
// InOrderTreeTraversal(viewedNode->rightChild);
|
||||
return;
|
||||
}
|
||||
|
||||
// Prints the given word's parent's word if found
|
||||
void TreeInterface::PrintParentKey(std::string key)
|
||||
{
|
||||
std::unique_ptr<TreeNode> foundNode = std::move(Search(key));
|
||||
if (!IsSearchSuccessful(foundNode)) return;
|
||||
std::cout << "The parent's word is " << foundNode->parent->key << '\n';
|
||||
// std::unique_ptr<TreeNode> foundNode = std::move(Search(key));
|
||||
// if (!IsSearchSuccessful(foundNode)) return;
|
||||
// std::cout << "The parent's word is " << foundNode->parent->key << '\n';
|
||||
return;
|
||||
}
|
||||
|
||||
// Prints the given word's left child's word if found
|
||||
void TreeInterface::PrintLeftChild(std::string key)
|
||||
{
|
||||
std::unique_ptr<TreeNode> foundNode = std::move(Search(key));
|
||||
if (!IsSearchSuccessful(foundNode)) return;
|
||||
std::cout << "The left child's word is " << foundNode->leftChild->key << '\n';
|
||||
// std::unique_ptr<TreeNode> foundNode = std::move(Search(key));
|
||||
// if (!IsSearchSuccessful(foundNode)) return;
|
||||
// std::cout << "The left child's word is " << foundNode->leftChild->key << '\n';
|
||||
return;
|
||||
}
|
||||
|
||||
// Prints the given word's right child's word if found
|
||||
void TreeInterface::PrintRightChild(std::string key)
|
||||
{
|
||||
std::unique_ptr<TreeNode> foundNode = std::move(Search(key));
|
||||
if (!IsSearchSuccessful(foundNode)) return;
|
||||
std::cout << "The right child's word is " << foundNode->rightChild->key << '\n';
|
||||
// std::unique_ptr<TreeNode> foundNode = std::move(Search(key));
|
||||
// if (!IsSearchSuccessful(foundNode)) return;
|
||||
// std::cout << "The right child's word is " << foundNode->rightChild->key << '\n';
|
||||
return;
|
||||
}
|
||||
|
||||
// Recursive insertion function for Insert()
|
||||
TreeNode* TreeInterface::Insert(std::unique_ptr<TreeNode> root, std::unique_ptr<TreeNode> newNode)
|
||||
{
|
||||
if (!tree.head)
|
||||
return newNode.release();
|
||||
if (newNode->key < root->key)
|
||||
{
|
||||
root->leftChild = _Insert(root->leftChild, newNode);
|
||||
root->leftChild->parent = root.release();
|
||||
} else if (newNode->key > root->key) {
|
||||
root->rightChild = _Insert(root->rightChild, newNode);
|
||||
root->rightChild->parent = root.release();
|
||||
}
|
||||
return root.release();
|
||||
// if (!tree.head)
|
||||
// return newNode.release();
|
||||
// if (newNode->key < root->key)
|
||||
// {
|
||||
// root->leftChild = Insert(root->leftChild, newNode);
|
||||
// root->leftChild->parent = root.release();
|
||||
// } else if (newNode->key > root->key) {
|
||||
// root->rightChild = Insert(root->rightChild, newNode);
|
||||
// root->rightChild->parent = root.release();
|
||||
// }
|
||||
// return root.release();
|
||||
}
|
||||
|
||||
// Recursive search function for Search()
|
||||
TreeNode* TreeInterface::Search(std::unique_ptr<TreeNode> viewedNode, std::string wordToFind)
|
||||
TreeNode* TreeInterface::Search(std::unique_ptr<TreeNode>* viewedNode, std::string wordToFind)
|
||||
{
|
||||
if ((!viewedNode) || (wordToFind == viewedNode->key))
|
||||
return viewedNode.release();
|
||||
if (wordToFind < viewedNode->key)
|
||||
return _Search(viewedNode->leftChild, wordToFind);
|
||||
return _Search(viewedNode->rightChild, wordToFind);
|
||||
// if ((!viewedNode) || (wordToFind == viewedNode->key))
|
||||
// return viewedNode.release();
|
||||
// if (wordToFind < viewedNode->key)
|
||||
// return Search(viewedNode->leftChild, wordToFind);
|
||||
// return Search(viewedNode->rightChild, wordToFind);
|
||||
}
|
||||
|
||||
// Insert a node into a BST
|
||||
void RedBlackTree::Insert(std::string keyToInsert)
|
||||
void BinarySearchTree::Insert(std::string keyToInsert)
|
||||
{
|
||||
std::unique_ptr<TreeNode> newNode = new TreeNode(keyToInsert);
|
||||
TreeInterface::Insert(newNode);
|
||||
// std::unique_ptr<TreeNode> newNode = new TreeNode(keyToInsert);
|
||||
// TreeInterface::Insert(newNode);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -160,17 +160,17 @@ namespace tree_implementation
|
||||
// TODO: Implement printing path to root for BST
|
||||
void BinarySearchTree::PrintPathToRoot(std::string key)
|
||||
{
|
||||
std::unique_ptr<TreeNode> selectedNode = std::move(Search(key));
|
||||
if (!IsSearchSuccessful(selectedNode)) return;
|
||||
int timesPrintedOnLine = 0;
|
||||
std::cout << "Path:\n" << selectedNode->key;
|
||||
do
|
||||
{
|
||||
selectedNode = selectedNode->parent;
|
||||
std::cout << " -> " << selectedNode->parent->key;
|
||||
if (timesPrintedOnLine < 10) ++timesPrintedOnLine;
|
||||
else std::cout << "\n";
|
||||
} while (selectedNode->parent);
|
||||
// std::unique_ptr<TreeNode> selectedNode = std::move(Search(key));
|
||||
// if (!IsSearchSuccessful(selectedNode)) return;
|
||||
// int timesPrintedOnLine = 0;
|
||||
// std::cout << "Path:\n" << selectedNode->key;
|
||||
// do
|
||||
// {
|
||||
// selectedNode = selectedNode->parent;
|
||||
// std::cout << " -> " << selectedNode->parent->key;
|
||||
// if (timesPrintedOnLine < 10) ++timesPrintedOnLine;
|
||||
// else std::cout << "\n";
|
||||
// } while (selectedNode->parent);
|
||||
|
||||
return;
|
||||
}
|
||||
@ -178,9 +178,9 @@ namespace tree_implementation
|
||||
// Insert a node into a RBT
|
||||
void RedBlackTree::Insert(std::string keyToInsert)
|
||||
{
|
||||
std::unique_ptr<TreeNode> newNode = new TreeNode(keyToInsert);
|
||||
TreeInterface::Insert(newNode);
|
||||
InsertFixup(newNode);
|
||||
// std::unique_ptr<TreeNode> newNode = new TreeNode(keyToInsert);
|
||||
// TreeInterface::Insert(newNode);
|
||||
// InsertFixup(newNode);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -194,104 +194,104 @@ namespace tree_implementation
|
||||
// Print color of word if found in RBT
|
||||
void RedBlackTree::PrintColor(std::string key)
|
||||
{
|
||||
std::unique_ptr<TreeNode> foundNode = std::move(Search(key));
|
||||
if (!IsSearchSuccessful(foundNode)) return;
|
||||
std::cout << "The color is " << foundNode->color << '\n';
|
||||
// std::unique_ptr<TreeNode> foundNode = std::move(Search(key));
|
||||
// if (!IsSearchSuccessful(foundNode)) return;
|
||||
// std::cout << "The color is " << foundNode->color << '\n';
|
||||
return;
|
||||
}
|
||||
|
||||
// Print color of word's parent if found in RBT
|
||||
void RedBlackTree::PrintParentColor(std::string key)
|
||||
{
|
||||
std::unique_ptr<TreeNode> foundNode = std::move(Search(key));
|
||||
if (!IsSearchSuccessful(foundNode)) return;
|
||||
std::cout << "The color is " << foundNode->parent->color << '\n';
|
||||
// std::unique_ptr<TreeNode> foundNode = std::move(Search(key));
|
||||
// if (!IsSearchSuccessful(foundNode)) return;
|
||||
// std::cout << "The color is " << foundNode->parent->color << '\n';
|
||||
return;
|
||||
}
|
||||
|
||||
// Print color of word's uncle if found in RBT
|
||||
void RedBlackTree::PrintUncleColor(std::string key)
|
||||
{
|
||||
std::unique_ptr<TreeNode> foundNode = std::move(Search(key));
|
||||
if (!IsSearchSuccessful(foundNode)) return;
|
||||
std::cout << "The color is " << GetUncleNode(foundNode)->color << '\n';
|
||||
// std::unique_ptr<TreeNode> foundNode = std::move(Search(key));
|
||||
// if (!IsSearchSuccessful(foundNode)) return;
|
||||
// std::cout << "The color is " << GetUncleNode(foundNode)->color << '\n';
|
||||
return;
|
||||
}
|
||||
|
||||
void RedBlackTree::InsertFixup(std::unique_ptr<TreeNode> z)
|
||||
{
|
||||
std::unique_ptr<TreeNode> y;
|
||||
while (z->parent->color == "red")
|
||||
{
|
||||
if (z->parent == z->parent->parent->leftChild)
|
||||
{
|
||||
y = std::move(z->parent->parent->rightChild);
|
||||
if (y->color == "red")
|
||||
{
|
||||
z->parent->color = "black";
|
||||
y->color = "black";
|
||||
z->parent->parent->color = "red";
|
||||
z = std::move(z->parent->parent);
|
||||
} else if (z == z->parent->rightChild) {
|
||||
z = std::move(z->parent);
|
||||
LeftRotate(z);
|
||||
z->parent->color = "black";
|
||||
z->parent->parent->color = "red";
|
||||
RightRotate(z->parent->parent);
|
||||
}
|
||||
} else {
|
||||
// same as then clause with "right" and "left" exchanged
|
||||
// TODO: Add else statement
|
||||
;
|
||||
}
|
||||
}
|
||||
tree.head->color = "black";
|
||||
// std::unique_ptr<TreeNode> y;
|
||||
// while (z->parent->color == "red")
|
||||
// {
|
||||
// if (z->parent == z->parent->parent->leftChild)
|
||||
// {
|
||||
// y = std::move(z->parent->parent->rightChild);
|
||||
// if (y->color == "red")
|
||||
// {
|
||||
// z->parent->color = "black";
|
||||
// y->color = "black";
|
||||
// z->parent->parent->color = "red";
|
||||
// z = std::move(z->parent->parent);
|
||||
// } else if (z == z->parent->rightChild) {
|
||||
// z = std::move(z->parent);
|
||||
// LeftRotate(z);
|
||||
// z->parent->color = "black";
|
||||
// z->parent->parent->color = "red";
|
||||
// RightRotate(z->parent->parent);
|
||||
// }
|
||||
// } else {
|
||||
// // same as then clause with "right" and "left" exchanged
|
||||
// // TODO: Add else statement
|
||||
// ;
|
||||
// }
|
||||
// }
|
||||
// tree.head->color = "black";
|
||||
return;
|
||||
}
|
||||
|
||||
// Returns the uncle node in RBT
|
||||
std::unique_ptr<TreeNode> RedBlackTree::GetUncleNode(std::unique_ptr<TreeNode> startNode)
|
||||
{
|
||||
if (startNode->parent == startNode->parent->parent->leftChild)
|
||||
return std::move(startNode->parent->parent->rightChild);
|
||||
return std::move(startNode->parent->parent->leftChild);
|
||||
// if (startNode->parent == startNode->parent->parent->leftChild)
|
||||
// return std::move(startNode->parent->parent->rightChild);
|
||||
// return std::move(startNode->parent->parent->leftChild);
|
||||
}
|
||||
|
||||
// Performs left rotate on a given node
|
||||
void RedBlackTree::LeftRotate(std::unique_ptr<TreeNode> x)
|
||||
{
|
||||
std::unique_ptr<TreeNode> y(std::move(x->rightChild));
|
||||
x->rightChild = std::move(y->leftChild);
|
||||
if (y->rightChild)
|
||||
y->rightChild->parent = std::move(x);
|
||||
y->parent = std::move(x->parent);
|
||||
if (!x->parent)
|
||||
tree.head = std::move(y);
|
||||
else if (x == x->parent->leftChild)
|
||||
x->parent->leftChild = std::move(y);
|
||||
else
|
||||
x->parent->rightChild = std::move(y);
|
||||
y->leftChild = std::move(x);
|
||||
x->parent = std::move(y);
|
||||
// std::unique_ptr<TreeNode> y(std::move(x->rightChild));
|
||||
// x->rightChild = std::move(y->leftChild);
|
||||
// if (y->rightChild)
|
||||
// y->rightChild->parent = std::move(x);
|
||||
// y->parent = std::move(x->parent);
|
||||
// if (!x->parent)
|
||||
// tree.head = std::move(y);
|
||||
// else if (x == x->parent->leftChild)
|
||||
// x->parent->leftChild = std::move(y);
|
||||
// else
|
||||
// x->parent->rightChild = std::move(y);
|
||||
// y->leftChild = std::move(x);
|
||||
// x->parent = std::move(y);
|
||||
return;
|
||||
}
|
||||
|
||||
// Performs right rotate on a given node
|
||||
void RedBlackTree::RightRotate(std::unique_ptr<TreeNode> x)
|
||||
{
|
||||
std::unique_ptr<TreeNode> y(std::move(x->rightChild));
|
||||
x->rightChild = std::move(y->leftChild);
|
||||
if (y->leftChild)
|
||||
y->leftChild->parent = std::move(x);
|
||||
y->parent = std::move(x->parent);
|
||||
if (!x->parent)
|
||||
tree.head = std::move(y);
|
||||
else if (x == x->parent->leftChild)
|
||||
x->parent->leftChild = std::move(y);
|
||||
else
|
||||
x->parent->rightChild = std::move(y);
|
||||
y->leftChild = std::move(x);
|
||||
x->parent = std::move(y);
|
||||
// std::unique_ptr<TreeNode> y(std::move(x->rightChild));
|
||||
// x->rightChild = std::move(y->leftChild);
|
||||
// if (y->leftChild)
|
||||
// y->leftChild->parent = std::move(x);
|
||||
// y->parent = std::move(x->parent);
|
||||
// if (!x->parent)
|
||||
// tree.head = std::move(y);
|
||||
// else if (x == x->parent->leftChild)
|
||||
// x->parent->leftChild = std::move(y);
|
||||
// else
|
||||
// x->parent->rightChild = std::move(y);
|
||||
// y->leftChild = std::move(x);
|
||||
// x->parent = std::move(y);
|
||||
return;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user