From 226bf8587a94e587a6115fd2aba2c751ebd2ffa4 Mon Sep 17 00:00:00 2001 From: TriantaTV Date: Mon, 6 Mar 2023 21:54:40 -0600 Subject: [PATCH] Added user interaction with BST and RBT --- Makefile | 1 + README.md | 14 +- include/interface.hpp | 33 ++++ include/sort_controller.hpp | 30 ++++ include/trees.hpp | 9 +- src/interface.cpp | 222 +++++++++++++++++++++++ src/main.cpp | 20 ++- src/sort_controller.cpp | 341 +++++++++++++++++++++++++++--------- src/trees.cpp | 86 ++++++--- 9 files changed, 640 insertions(+), 116 deletions(-) create mode 100644 include/interface.hpp create mode 100644 src/interface.cpp diff --git a/Makefile b/Makefile index b253a16..59b9b29 100644 --- a/Makefile +++ b/Makefile @@ -5,6 +5,7 @@ main: compile link compile: g++ $(INC) $(STD) -c -o build/main.o src/main.cpp + g++ $(INC) $(STD) -c -o build/interface.o src/interface.cpp g++ $(INC) $(STD) -c -o build/sort_controller.o src/sort_controller.cpp g++ $(INC) $(STD) -c -o build/basic_sorts.o src/basic_sorts.cpp g++ $(INC) $(STD) -c -o build/trees.o src/trees.cpp diff --git a/README.md b/README.md index b673838..34c72ae 100644 --- a/README.md +++ b/README.md @@ -22,14 +22,17 @@ Ex: `bin/main.out -f test/PERM/perm15K.txt -s bst -l apple` ## File selection > -a | --all - - Runs through all the original files (perm15K.txt - perm150K.txt) + - Runs through all the original files (test/PERM/perm[15-150]K.txt) - *EX: bin/main.out -a* > -f path/to/file.txt | --filename path/to/file.txt - Runs a specific file to sort - *EX: bin/main.out -f perm15K.txt* > -d | --default - - Runs sort only on the default test file (perm15K.txt) + - Runs sort only on the default test file (located test/PERM/perm15K.txt) - *EX: bin/main.out -d* +> -o | --output + - Set file for outputting InOrderTreeTraversal + - *EX: bin/main.out -f test/PERM/perm15K.txt -s bst -o test/traversal.txt* ## Sorting type selection > -s | --sort-type @@ -48,9 +51,6 @@ Ex: `bin/main.out -f test/PERM/perm15K.txt -s bst -l apple` - all (only runs insertion, merge, and heap sort) - *EX: bin/main.out -s all* -## Locating a word -> -l | --locate - - Locates a word and prints the output [***default***] - - Must be used with BST or RBT sort type - - *EX: bin/main.out -l apple* # Notes + - Filename for i/o and implementation are preselected through the CLI. + - BST and RBT specific methods are called once program has constructed it diff --git a/include/interface.hpp b/include/interface.hpp new file mode 100644 index 0000000..500f462 --- /dev/null +++ b/include/interface.hpp @@ -0,0 +1,33 @@ +#ifndef INTERFACE_HPP +#define INTERFACE_HPP + +#include "sort_controller.hpp" +#include +#include + +class Interface +{ +public: + SortController benchmark; + Interface(void); + void CheckArguments(int argc, char* arguments[]); + void Construction(void); + bool IsBST(void); + bool IsOnlySorting(void); + void Sort(void); + bool UserInput(void); + void BSTRequestExecution(void); + void RBTRequestExecution(void); +protected: + ; +private: + int userInput; + std::string givenWord; + SortType currentType; + bool allLists, sortGiven; + void CheckRequirements(void); + void PrintHelp(void); + void PrintOptions(void); +}; + +#endif \ No newline at end of file diff --git a/include/sort_controller.hpp b/include/sort_controller.hpp index c8ebba2..0183a0e 100644 --- a/include/sort_controller.hpp +++ b/include/sort_controller.hpp @@ -1,7 +1,9 @@ #ifndef SORT_CONTROLLER_HPP #define SORT_CONTROLLER_HPP +#include "trees.hpp" #include +#include #include #include @@ -14,12 +16,40 @@ public: void CheckArguments(int argc, char* arguments[]); void ReadWordFile(void); void RunBenchmarks(void); + void SetFilename(std::string name); + std::string GetFilename(void); + void SetOutput(std::string filename); + void TestInsertion(void); + void TestMerge(void); + void TestHeap(void); + void ConstructBST(void); + void ConstructRBT(void); + void BSTInsert(std::string key); + void BSTSearch(std::string key); + void BSTInOrderTreeTraversal(std::string key); + void BSTPrintParentKey(std::string key); + void BSTPrintLeftChild(std::string key); + void BSTPrintRightChild(std::string key); + void BSTPrintPathToRoot(std::string key); + void RBTInsert(std::string key); + void RBTSearch(std::string key); + void RBTInOrderTreeTraversal(std::string key); + void RBTPrintParentKey(std::string key); + void RBTPrintLeftChild(std::string key); + void RBTPrintRightChild(std::string key); + void RBTPrintPathToRoot(std::string key); + void RBTPrintColor(std::string key); + void RBTPrintParentColor(std::string key); + void RBTPrintUncleColor(std::string key); protected: ; private: std::string filename; + std::ofstream outputFile; SortType currentType; std::string wordToLocate; + tree_implementation::BinarySearchTree binarySearchTree; + tree_implementation::RedBlackTree redBlackTree; std::chrono::duration sortTime; std::vector newWordList; std::vector originalWordList; diff --git a/include/trees.hpp b/include/trees.hpp index fe06f57..9f1adf3 100644 --- a/include/trees.hpp +++ b/include/trees.hpp @@ -1,6 +1,7 @@ #ifndef TREES_HPP #define TREES_HPP +#include #include #include #include @@ -42,18 +43,20 @@ namespace tree_implementation public: TreeList tree; TreeInterface(void); - std::shared_ptr Search(std::string wordToFind); - bool IsSearchSuccessful(std::shared_ptr foundNode, std::string key); + void Search(std::string key); + std::shared_ptr GetNodeWithWord(std::string wordToFind); void InOrderTreeTraversal(std::shared_ptr viewedNode); + void InOrderTreeTraversal(std::shared_ptr viewedNode, std::ofstream file); void PrintParentKey(std::string key); void PrintLeftChild(std::string key); void PrintRightChild(std::string key); protected: + bool IsNodeSearchSuccessful(std::shared_ptr foundNode, std::string key); virtual void Insert(std::shared_ptr z); virtual void InsertWordList(std::vector* newWordList) = 0; virtual void PrintPathToRoot(std::string key) = 0; private: - std::shared_ptr Search(std::shared_ptr viewedNode, std::string wordToFind); + std::shared_ptr GetNodeWithWord(std::shared_ptr viewedNode, std::string wordToFind); }; // Binary Search Tree operations diff --git a/src/interface.cpp b/src/interface.cpp new file mode 100644 index 0000000..9a9191b --- /dev/null +++ b/src/interface.cpp @@ -0,0 +1,222 @@ +#include "interface.hpp" +#include +#include +#include +#include + +Interface::Interface(void) +{ + currentType = INSERTION; + allLists = 0; + sortGiven = 0; + return; +} + +// Checks for command line arguments +void Interface::CheckArguments(int argc, char* arguments[]) +{ + std::string tempStr; + for (int i = 0; i < argc; i++) + { + tempStr = arguments[i]; + if ((tempStr == "-a") || (tempStr == "--all")) + allLists = 1; + if ((tempStr == "-f") || (tempStr == "--filename")) + benchmark.SetFilename(arguments[i + 1]); + if ((tempStr == "-d") || (tempStr == "--default")) + benchmark.SetFilename("test/PERM/perm15K.txt"); + if ((tempStr == "-o") || (tempStr == "--output")) + benchmark.SetOutput(arguments[i + 1]); + if ((tempStr == "-s") || (tempStr == "--sort-type")) + { + sortGiven = 1; + tempStr = arguments[i + 1]; + if (tempStr == "bst") + currentType = BST; + if (tempStr == "rbt") + currentType = RBT; + if (tempStr == "insertion") + currentType = INSERTION; + if (tempStr == "merge") + currentType = MERGE; + if (tempStr == "heap") + currentType = HEAP; + if (tempStr == "all") + sortGiven = 0; + } + } + return; +} + +void Interface::Construction(void) +{ + CheckRequirements(); + benchmark.ReadWordFile(); + if (currentType == BST) + benchmark.ConstructBST(); + if (currentType == RBT) + benchmark.ConstructRBT(); +} + +bool Interface::IsBST(void) +{ + if (currentType == BST) return true; + return false; +} + +bool Interface::IsOnlySorting(void) +{ + if ((currentType == INSERTION) || (currentType == MERGE) || (currentType == HEAP)) + return true; + return false; +} + +void Interface::Sort(void) +{ + ; +} + +bool Interface::UserInput(void) +{ + PrintOptions(); + std::cin >> userInput; + if (!userInput) return 0; + std::cout << "Enter word you wish to find: "; + std::cin >> givenWord; + std::transform(givenWord.begin(), givenWord.end(), givenWord.begin(), ::toupper); + std::cout << std::endl; + return 1; +} + + +void Interface::BSTRequestExecution(void) +{ + switch (userInput) + { + case 1: + // Insert + benchmark.BSTInsert(givenWord); + break; + case 2: + // Search + benchmark.BSTSearch(givenWord); + break; + case 3: + // InOrderTreeTraversal + benchmark.BSTInOrderTreeTraversal(givenWord); + break; + case 4: + // PrintParentKey + benchmark.BSTPrintParentKey(givenWord); + break; + case 5: + // PrintLeftChild + benchmark.BSTPrintLeftChild(givenWord); + break; + case 6: + // PrintRightChild + benchmark.BSTPrintRightChild(givenWord); + break; + case 7: + // PrintPathToRoot + benchmark.BSTPrintPathToRoot(givenWord); + break; + case 8: + // PrintColor + std::cout << "This method is not available for BST" << std::endl; + break; + case 9: + // PrintParentColor + std::cout << "This method is not available for BST" << std::endl; + break; + case 10: + // PrintUncleColor + std::cout << "This method is not available for BST" << std::endl; + break; + default: + std::cout << "Please enter a valid option." << std::endl; + std::cout << std::endl << std::endl << std::endl; + break; + } +} + +void Interface::RBTRequestExecution(void) +{ + switch (userInput) + { + case 1: + // Insert + benchmark.RBTInsert(givenWord); + break; + case 2: + // Search + benchmark.RBTSearch(givenWord); + break; + case 3: + // InOrderTreeTraversal + benchmark.RBTInOrderTreeTraversal(givenWord); + break; + case 4: + // PrintParentKey + benchmark.RBTPrintParentKey(givenWord); + break; + case 5: + // PrintLeftChild + benchmark.RBTPrintLeftChild(givenWord); + break; + case 6: + // PrintRightChild + benchmark.RBTPrintRightChild(givenWord); + break; + case 7: + // PrintPathToRoot + benchmark.RBTPrintPathToRoot(givenWord); + break; + case 8: + // PrintColor + benchmark.RBTPrintColor(givenWord); + break; + case 9: + // PrintParentColor + benchmark.RBTPrintParentColor(givenWord); + break; + case 10: + // PrintUncleColor + benchmark.RBTPrintUncleColor(givenWord); + break; + default: + std::cout << "Please enter a valid option." << std::endl; + std::cout << std::endl << std::endl << std::endl; + break; + } +} + +void Interface::CheckRequirements(void) +{ + if (!sortGiven) + { + std::cout << "Please enter a sorting type to use." << std::endl; + exit(1); + } + return; +} + +void Interface::PrintOptions(void) +{ + std::cout << "General Options:" << std::endl; + std::cout << "\t1) Insert" << std::endl; + std::cout << "\t2) Search" << std::endl; + std::cout << "\t3) InOrderTreeTraversal" << std::endl; + std::cout << "\t4) PrintParentKey" << std::endl; + std::cout << "\t5) PrintLeftChild" << std::endl; + std::cout << "\t6) PrintRightChild" << std::endl; + std::cout << "\t7) PrintPathToRoot" << std::endl; + std::cout << "Options for RBT:" << std::endl; + std::cout << "\t8) PrintColor" << std::endl; + std::cout << "\t9) PrintParentColor" << std::endl; + std::cout << "\t10) PrintUncleColor" << std::endl; + std::cout << "\t0) Exit" << std::endl; + std::cout << "Enter the number of the option you wish to use: "; + return; +} + diff --git a/src/main.cpp b/src/main.cpp index ccb8fb2..5d6c8ba 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,9 +1,21 @@ -#include "sort_controller.hpp" +#include "interface.hpp" int main(int argc, char* argv[]) { - SortController benchmark; - benchmark.CheckArguments(argc, argv); - benchmark.RunBenchmarks(); + Interface session; + session.CheckArguments(argc, argv); + session.Construction(); + if (session.IsOnlySorting()) + { + session.Sort(); + return 0; + } + while (session.UserInput()) + { + if (session.IsBST()) + session.BSTRequestExecution(); + else + session.RBTRequestExecution(); + } return 0; } diff --git a/src/sort_controller.cpp b/src/sort_controller.cpp index 5ee081f..1dc1398 100644 --- a/src/sort_controller.cpp +++ b/src/sort_controller.cpp @@ -13,11 +13,10 @@ SortController::SortController() { lineCount = 0; currentType = INSERTION; - defaultFile = 0; - defaultOnly = 1; - fileGiven = 0; + filename = "test/PERM/perm15K.txt"; allLists = 0; sortGiven = 0; + return; } // Checks for command line arguments @@ -29,14 +28,11 @@ void SortController::CheckArguments(int argc, char* arguments[]) tempStr = arguments[i]; if ((tempStr == "-a") || (tempStr == "--all")) { - defaultOnly = 0; allLists = 1; } if ((tempStr == "-f") || (tempStr == "--filename")) { filename = arguments[i + 1]; - defaultOnly = 0; - fileGiven = 1; } if ((tempStr == "-l") || (tempStr == "--locate")) { @@ -47,7 +43,6 @@ void SortController::CheckArguments(int argc, char* arguments[]) if ((tempStr == "-d") || (tempStr == "--default")) { filename = "test/PERM/perm15K.txt"; - defaultFile = 1; } if ((tempStr == "-s") || (tempStr == "--sort-type")) { @@ -67,8 +62,6 @@ void SortController::CheckArguments(int argc, char* arguments[]) sortGiven = 0; } } - if (defaultOnly) - filename = "test/PERM/perm15K.txt"; return; } @@ -93,85 +86,275 @@ void SortController::ReadWordFile(void) // Main function for calling all sort categories void SortController::RunBenchmarks(void) { - if (defaultOnly || fileGiven) - { - ReadWordFile(); - Benchmarking(); - } if (allLists) + { BenchmarkingAll(); + return; + } + ReadWordFile(); + Benchmarking(); return; } +void SortController::SetFilename(std::string name) +{ + filename = name; + return; +} + +std::string SortController::GetFilename(void) +{ + return filename; +} + +void SortController::SetOutput(std::string filename) +{ + outputFile.open(filename); + return; +} + +void SortController::TestInsertion(void) +{ + newWordList = originalWordList; + auto start = std::chrono::system_clock::now(); + basic_sorts::InsertionSort(&newWordList); + auto end = std::chrono::system_clock::now(); + sortTime = end - start; + OutputResult(); +} + +void SortController::TestMerge(void) +{ + newWordList = originalWordList; + auto start = std::chrono::system_clock::now(); + basic_sorts::MergeSort(&newWordList); + auto end = std::chrono::system_clock::now(); + sortTime = end - start; + OutputResult(); +} + +void SortController::TestHeap(void) +{ + newWordList = originalWordList; + auto start = std::chrono::system_clock::now(); + basic_sorts::HeapSort(&newWordList); + auto end = std::chrono::system_clock::now(); + sortTime = end - start; + OutputResult(); +} + +void SortController::ConstructBST(void) +{ + newWordList = originalWordList; + auto start = std::chrono::system_clock::now(); + binarySearchTree.InsertWordList(&newWordList); + auto end = std::chrono::system_clock::now(); + sortTime = end - start; + OutputResult(); +} + +void SortController::ConstructRBT(void) +{ + newWordList = originalWordList; + tree_implementation::RedBlackTree newTree; + auto start = std::chrono::system_clock::now(); + newTree.InsertWordList(&newWordList); + auto end = std::chrono::system_clock::now(); + sortTime = end - start; + OutputResult(); +} + +void SortController::BSTInsert(std::string key) +{ + auto start = std::chrono::system_clock::now(); + binarySearchTree.Insert(key); + auto end = std::chrono::system_clock::now(); + sortTime = end - start; + std::cout << "Operation took " << sortTime.count() << 's' << std::endl; +} + +void SortController::BSTSearch(std::string key) +{ + auto start = std::chrono::system_clock::now(); + binarySearchTree.Search(key); + auto end = std::chrono::system_clock::now(); + sortTime = end - start; + std::cout << "Operation took " << sortTime.count() << 's' << std::endl; +} + +void SortController::BSTInOrderTreeTraversal(std::string key) +{ + auto start = std::chrono::system_clock::now(); + binarySearchTree.InOrderTreeTraversal(redBlackTree.GetNodeWithWord(key)); + auto end = std::chrono::system_clock::now(); + sortTime = end - start; + std::cout << "Operation took " << sortTime.count() << 's' << std::endl; +} + +void SortController::BSTPrintParentKey(std::string key) +{ + auto start = std::chrono::system_clock::now(); + binarySearchTree.PrintParentKey(key); + auto end = std::chrono::system_clock::now(); + sortTime = end - start; + std::cout << "Operation took " << sortTime.count() << 's' << std::endl; +} + +void SortController::BSTPrintLeftChild(std::string key) +{ + auto start = std::chrono::system_clock::now(); + binarySearchTree.PrintLeftChild(key); + auto end = std::chrono::system_clock::now(); + sortTime = end - start; + std::cout << "Operation took " << sortTime.count() << 's' << std::endl; +} + +void SortController::BSTPrintRightChild(std::string key) +{ + auto start = std::chrono::system_clock::now(); + binarySearchTree.PrintRightChild(key); + auto end = std::chrono::system_clock::now(); + sortTime = end - start; + std::cout << "Operation took " << sortTime.count() << 's' << std::endl; +} + +void SortController::BSTPrintPathToRoot(std::string key) +{ + auto start = std::chrono::system_clock::now(); + binarySearchTree.PrintPathToRoot(key); + auto end = std::chrono::system_clock::now(); + sortTime = end - start; + std::cout << "Operation took " << sortTime.count() << 's' << std::endl; +} + +void SortController::RBTInsert(std::string key) +{ + auto start = std::chrono::system_clock::now(); + redBlackTree.Insert(key); + auto end = std::chrono::system_clock::now(); + sortTime = end - start; + std::cout << "Operation took " << sortTime.count() << 's' << std::endl; +} + +void SortController::RBTSearch(std::string key) +{ + auto start = std::chrono::system_clock::now(); + redBlackTree.Search(key); + auto end = std::chrono::system_clock::now(); + sortTime = end - start; + std::cout << "Operation took " << sortTime.count() << 's' << std::endl; +} + +void SortController::RBTInOrderTreeTraversal(std::string key) +{ + auto start = std::chrono::system_clock::now(); + redBlackTree.InOrderTreeTraversal(redBlackTree.GetNodeWithWord(key)); + auto end = std::chrono::system_clock::now(); + sortTime = end - start; + std::cout << "Operation took " << sortTime.count() << 's' << std::endl; +} + +void SortController::RBTPrintParentKey(std::string key) +{ + auto start = std::chrono::system_clock::now(); + redBlackTree.PrintParentKey(key); + auto end = std::chrono::system_clock::now(); + sortTime = end - start; + std::cout << "Operation took " << sortTime.count() << 's' << std::endl; +} + +void SortController::RBTPrintLeftChild(std::string key) +{ + auto start = std::chrono::system_clock::now(); + redBlackTree.PrintLeftChild(key); + auto end = std::chrono::system_clock::now(); + sortTime = end - start; + std::cout << "Operation took " << sortTime.count() << 's' << std::endl; +} + +void SortController::RBTPrintRightChild(std::string key) +{ + auto start = std::chrono::system_clock::now(); + redBlackTree.PrintRightChild(key); + auto end = std::chrono::system_clock::now(); + sortTime = end - start; + std::cout << "Operation took " << sortTime.count() << 's' << std::endl; +} + +void SortController::RBTPrintPathToRoot(std::string key) +{ + auto start = std::chrono::system_clock::now(); + redBlackTree.PrintPathToRoot(key); + auto end = std::chrono::system_clock::now(); + sortTime = end - start; + std::cout << "Operation took " << sortTime.count() << 's' << std::endl; +} + +void SortController::RBTPrintColor(std::string key) +{ + auto start = std::chrono::system_clock::now(); + redBlackTree.PrintColor(key); + auto end = std::chrono::system_clock::now(); + sortTime = end - start; + std::cout << "Operation took " << sortTime.count() << 's' << std::endl; +} + +void SortController::RBTPrintParentColor(std::string key) +{ + auto start = std::chrono::system_clock::now(); + redBlackTree.PrintParentColor(key); + auto end = std::chrono::system_clock::now(); + sortTime = end - start; + std::cout << "Operation took " << sortTime.count() << 's' << std::endl; +} + +void SortController::RBTPrintUncleColor(std::string key) +{ + auto start = std::chrono::system_clock::now(); + redBlackTree.PrintUncleColor(key); + auto end = std::chrono::system_clock::now(); + sortTime = end - start; + std::cout << "Operation took " << sortTime.count() << 's' << std::endl; +} + + +// TODO: Depreciated; Clean up // Function for starting sort functions void SortController::Benchmarking(void) { - if (!sortGiven) - currentType = INSERTION; - if (currentType == INSERTION) - { - newWordList = originalWordList; - auto start = std::chrono::system_clock::now(); - basic_sorts::InsertionSort(&newWordList); - auto end = std::chrono::system_clock::now(); - sortTime = end - start; - OutputResult(); - } - if (!sortGiven) - currentType = MERGE; - if (currentType == MERGE) - { - newWordList = originalWordList; - auto start = std::chrono::system_clock::now(); - basic_sorts::MergeSort(&newWordList); - auto end = std::chrono::system_clock::now(); - sortTime = end - start; - OutputResult(); - } - if (!sortGiven) - currentType = HEAP; - if (currentType == HEAP) - { - newWordList = originalWordList; - auto start = std::chrono::system_clock::now(); - basic_sorts::HeapSort(&newWordList); - auto end = std::chrono::system_clock::now(); - sortTime = end - start; - OutputResult(); - } - if (currentType == BST) - { - newWordList = originalWordList; - tree_implementation::BinarySearchTree newTree; - auto start = std::chrono::system_clock::now(); - newTree.InsertWordList(&newWordList); - auto end = std::chrono::system_clock::now(); - sortTime = end - start; - OutputResult(); - start = std::chrono::system_clock::now(); - newTree.Search(wordToLocate); - end = std::chrono::system_clock::now(); - sortTime = end - start; - EchoSortTime("BST"); - newTree.PrintPathToRoot(wordToLocate); - } - if (currentType == RBT) - { - newWordList = originalWordList; - tree_implementation::RedBlackTree newTree; - auto start = std::chrono::system_clock::now(); - newTree.InsertWordList(&newWordList); - auto end = std::chrono::system_clock::now(); - sortTime = end - start; - OutputResult(); - start = std::chrono::system_clock::now(); - newTree.Search(wordToLocate); - end = std::chrono::system_clock::now(); - sortTime = end - start; - EchoSortTime("RBT"); - newTree.PrintPathToRoot(wordToLocate); - } + // if (!sortGiven) + // currentType = INSERTION; + // if (currentType == INSERTION) + // { + + // } + // if (!sortGiven) + // currentType = MERGE; + // if (currentType == MERGE) + // { + + // } + // if (!sortGiven) + // currentType = HEAP; + // if (currentType == HEAP) + // { + + // } + // if (currentType == BST) + // { + + // } + // if (currentType == RBT) + // { + + // start = std::chrono::system_clock::now(); + // newTree.Search(wordToLocate); + // end = std::chrono::system_clock::now(); + // sortTime = end - start; + // EchoSortTime("RBT"); + // newTree.PrintPathToRoot(wordToLocate); + // } } // Sorts all default files if allLists is set diff --git a/src/trees.cpp b/src/trees.cpp index 222a52b..6dc8847 100644 --- a/src/trees.cpp +++ b/src/trees.cpp @@ -1,4 +1,5 @@ #include "trees.hpp" +#include #include #include #include @@ -28,6 +29,15 @@ namespace tree_implementation return; } + void TreeInterface::Search(std::string key) + { + std::cout << std::endl; + std::shared_ptr foundNode = GetNodeWithWord(key); + if (!IsNodeSearchSuccessful(foundNode, key)) return; + std::cout << "The word '" << key << "' was found in the tree."; + std::cout << std::endl; + } + // Inserts a node into a BST void TreeInterface::Insert(std::shared_ptr z) { @@ -52,12 +62,13 @@ namespace tree_implementation } // Searches for the given word in a tree - std::shared_ptr TreeInterface::Search(std::string wordToFind) + // Returns a pointer to the node + std::shared_ptr TreeInterface::GetNodeWithWord(std::string wordToFind) { - return Search(tree.head, wordToFind); + return GetNodeWithWord(tree.head, wordToFind); } - bool TreeInterface::IsSearchSuccessful(std::shared_ptr foundNode, std::string key) + bool TreeInterface::IsNodeSearchSuccessful(std::shared_ptr foundNode, std::string key) { if (foundNode) return true; @@ -69,17 +80,36 @@ namespace tree_implementation void TreeInterface::InOrderTreeTraversal(std::shared_ptr viewedNode) { if (viewedNode) + { InOrderTreeTraversal(viewedNode->leftChild); std::cout << viewedNode.get()->key << '\n'; InOrderTreeTraversal(viewedNode->rightChild); + } + return; + } + + // Prints tree while traversing it to a file + void TreeInterface::InOrderTreeTraversal(std::shared_ptr viewedNode, std::ofstream file) + { + if (viewedNode) + { + InOrderTreeTraversal(viewedNode->leftChild); + file << viewedNode.get()->key << '\n'; + InOrderTreeTraversal(viewedNode->rightChild); + } return; } // Prints the given word's parent's word if found void TreeInterface::PrintParentKey(std::string key) { - std::shared_ptr foundNode = Search(key); - if (!IsSearchSuccessful(foundNode, key)) return; + std::shared_ptr foundNode = GetNodeWithWord(key); + if (!IsNodeSearchSuccessful(foundNode, key)) return; + if (!foundNode->parent) + { + std::cout << "NIL" << std::endl; + return; + } std::cout << "The parent's word is " << foundNode->parent->key << '\n'; return; } @@ -87,8 +117,13 @@ namespace tree_implementation // Prints the given word's left child's word if found void TreeInterface::PrintLeftChild(std::string key) { - std::shared_ptr foundNode = Search(key); - if (!IsSearchSuccessful(foundNode, key)) return; + std::shared_ptr foundNode = GetNodeWithWord(key); + if (!IsNodeSearchSuccessful(foundNode, key)) return; + if (!foundNode->leftChild) + { + std::cout << "NIL" << std::endl; + return; + } std::cout << "The left child's word is " << foundNode->leftChild->key << '\n'; return; } @@ -96,20 +131,25 @@ namespace tree_implementation // Prints the given word's right child's word if found void TreeInterface::PrintRightChild(std::string key) { - std::shared_ptr foundNode = Search(key); - if (!IsSearchSuccessful(foundNode, key)) return; + std::shared_ptr foundNode = GetNodeWithWord(key); + if (!IsNodeSearchSuccessful(foundNode, key)) return; + if (!foundNode->rightChild) + { + std::cout << "NIL" << std::endl; + return; + } std::cout << "The right child's word is " << foundNode->rightChild->key << '\n'; return; } - // Recursive search function for Search() - std::shared_ptr TreeInterface::Search(std::shared_ptr viewedNode, std::string wordToFind) + // Recursive search function for GetNodeWithWord() + std::shared_ptr TreeInterface::GetNodeWithWord(std::shared_ptr viewedNode, std::string wordToFind) { if ((!viewedNode) || (wordToFind == viewedNode.get()->key)) return viewedNode; if (wordToFind < viewedNode.get()->key) - return Search(viewedNode->leftChild, wordToFind); - return Search(viewedNode->rightChild, wordToFind); + return GetNodeWithWord(viewedNode->leftChild, wordToFind); + return GetNodeWithWord(viewedNode->rightChild, wordToFind); } // Insert a node into a BST @@ -132,8 +172,8 @@ namespace tree_implementation // Prints the path to root in a BST void BinarySearchTree::PrintPathToRoot(std::string key) { - std::shared_ptr selectedNode = Search(key); - if (!IsSearchSuccessful(selectedNode, key)) return; + std::shared_ptr selectedNode = GetNodeWithWord(key); + if (!IsNodeSearchSuccessful(selectedNode, key)) return; int timesPrintedOnLine = 0; std::cout << "Path from:" << selectedNode->key << std::endl; while (selectedNode = selectedNode.get()->parent) @@ -173,8 +213,8 @@ namespace tree_implementation // TODO: Implement printing path to root for RBT void RedBlackTree::PrintPathToRoot(std::string key) { - std::shared_ptr selectedNode = Search(key); - if (!IsSearchSuccessful(selectedNode, key)) return; + std::shared_ptr selectedNode = GetNodeWithWord(key); + if (!IsNodeSearchSuccessful(selectedNode, key)) return; int timesPrintedOnLine = 0; std::cout << "Path from:" << selectedNode->key << std::endl; while (selectedNode = selectedNode.get()->parent) @@ -196,8 +236,8 @@ namespace tree_implementation // Print color of word if found in RBT void RedBlackTree::PrintColor(std::string key) { - std::shared_ptr foundNode = Search(key); - if (!IsSearchSuccessful(foundNode, key)) return; + std::shared_ptr foundNode = GetNodeWithWord(key); + if (!IsNodeSearchSuccessful(foundNode, key)) return; std::cout << "The color is " << foundNode->color << '\n'; return; } @@ -205,8 +245,8 @@ namespace tree_implementation // Print color of word's parent if found in RBT void RedBlackTree::PrintParentColor(std::string key) { - std::shared_ptr foundNode = Search(key); - if (!IsSearchSuccessful(foundNode, key)) return; + std::shared_ptr foundNode = GetNodeWithWord(key); + if (!IsNodeSearchSuccessful(foundNode, key)) return; std::cout << "The color is " << foundNode->parent->color << '\n'; return; } @@ -214,8 +254,8 @@ namespace tree_implementation // Print color of word's uncle if found in RBT void RedBlackTree::PrintUncleColor(std::string key) { - std::shared_ptr foundNode = Search(key); - if (!IsSearchSuccessful(foundNode, key)) return; + std::shared_ptr foundNode = GetNodeWithWord(key); + if (!IsNodeSearchSuccessful(foundNode, key)) return; std::cout << "The color is " << GetUncleNode(foundNode).get()->color << '\n'; return; }