diff --git a/CMakeLists.txt b/CMakeLists.txt index 4a533a3..ebffa5c 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.5) -set(BLT_VERSION 0.9.0) +set(BLT_VERSION 0.10.1) set(BLT_TEST_VERSION 0.0.1) project(BLT VERSION ${BLT_VERSION}) diff --git a/include/blt/std/binary_tree.h b/include/blt/std/binary_tree.h index 4ba4088..3d09e83 100755 --- a/include/blt/std/binary_tree.h +++ b/include/blt/std/binary_tree.h @@ -20,206 +20,7 @@ namespace blt { explicit binary_search_tree_error(const std::string& string): runtime_error(string) {} }; - template - class node_binary_search_tree { - protected: - struct BST_node { - BST_node* left = nullptr; - BST_node* right = nullptr; - T payload; - - explicit BST_node(const T& _payload) { - payload = _payload; - } - }; - BST_node* m_root = nullptr; - private: - void insert(BST_node* root, const T& element) { - if (root == nullptr) - throw binary_search_tree_error{"Unable to insert. Provided root is null!\n"}; - BST_node* searchNode = root; - // basically we are iterating through the tree looking for a valid node to insert into. - while (true) { - if (element == searchNode->payload) - throw binary_search_tree_error{"Unable to insert. Nodes cannot have equal values! (" + std::to_string(element) + ")\n"}; - // check for left and right tree traversal if it exists - if (searchNode->left != nullptr && element < searchNode->payload) { - searchNode = searchNode->left; - continue; - } - if (searchNode->right != nullptr && element > searchNode->payload) { - searchNode = searchNode->right; - continue; - } - // insert into the lowest node consistent with a BST - if (element < searchNode->payload) - searchNode->left = new BST_node(element); - else - searchNode->right = new BST_node(element); - return; - } - } - - BST_node* search(BST_node** parent, const T& element) const { - BST_node* searchNode = m_root; - BST_node* parentNode = m_root; - - if (searchNode->left == nullptr && searchNode->right == nullptr) - return nullptr; - - // basically we are iterating through the tree looking for a valid node to insert into. - while (searchNode->payload != element) { - if (searchNode == nullptr) - return nullptr; - // check for left and right tree traversal if it exists - if (element < searchNode->payload) { - parentNode = searchNode; - searchNode = searchNode->left; - } else { - parentNode = searchNode; - searchNode = searchNode->right; - } - } - if (parent != nullptr) - *parent = parentNode; - return searchNode; - } - - std::vector inOrderTraverse(BST_node* root) { - std::vector nodes{}; - blt::flat_stack nodeStack{}; - - BST_node* current = root; - while (current != nullptr || !nodeStack.empty()) { - // go all the way to the left subtree - while (current != nullptr) { - nodeStack.push(current); - current = current->left; - } - // take the parent node of the left most subtree - current = nodeStack.top(); - nodeStack.pop(); - nodes.push_back(current); - // traverse its right tree - current = current->right; - } - - return nodes; - } - - BST_node*& findMin(BST_node* root) { - BST_node*& searchNode = root; - while (searchNode->left != nullptr) - searchNode = searchNode->left; - return searchNode; - } - - BST_node*& findMax(BST_node* root) { - BST_node*& searchNode = root; - while (searchNode->right != nullptr) - searchNode = searchNode->right; - return searchNode; - } - - BST_node* remove(BST_node* root, const T& element) { - if (root->payload < element) // search left - root->left = remove(root->left, element); - else if (root->payload > element) // search right - root->right = remove(root->right, element); - else { - if (root->left != nullptr && root->right != nullptr) { - root->payload = findMin(root->right)->payload; - root->right = remove(root->right, root->payload); - } - } - return root; - } - public: - node_binary_search_tree() = default; - - inline void insert(const T& element) { - if (m_root == nullptr) { - m_root = new BST_node(element); - return; - } - insert(m_root, element); - } - - [[nodiscard]] inline BST_node* search(const T& element) const { - return search(nullptr, element); - } - - void remove(const T& element) { - BST_node* parent = nullptr; - BST_node* elementNode = search(&parent, element); - if (parent == elementNode) - parent = nullptr; - - if (elementNode->left != nullptr && elementNode->right != nullptr) { - auto traverseNodes = inOrderTraverse(elementNode); - if (parent == nullptr) { - m_root = nullptr; - } else { - // remove references to the nodes, we will add them later. We have a copy of the pointers which will be deleted. - if (parent->right == elementNode) - parent->right = nullptr; - else if (parent->left == elementNode) - parent->left = nullptr; - else - throw binary_search_tree_error("Parent node doesn't own child!\n"); - } - // re-add all nodes to the tree, this is a terrible way of doing this, TODO. - for (auto* node : traverseNodes) { - if (node != elementNode) { - if (parent == nullptr) { - insert(node->payload); - } else - insert(parent, node->payload); - delete(node); - } - } - } else { - auto replacementNode = elementNode->left != nullptr ? elementNode->left : elementNode->right; - if (parent == nullptr) - m_root = replacementNode; - else { - if (parent->right == elementNode) - parent->right = replacementNode; - else if (parent->left == elementNode) - parent->left = replacementNode; - else - throw binary_search_tree_error("Parent node doesn't contain element of search!\n"); - } - } - delete (elementNode); - } - - inline std::vector inOrderTraverse() { - return inOrderTraverse(m_root); - } - - inline BST_node* findMin(){return findMin(m_root);} - inline BST_node* findMax(){return findMax(m_root);} - - ~node_binary_search_tree() { - auto inOrder = inOrderTraverse(); - for (auto* n : inOrder) - delete(n); - } - }; - template - class heap { - private: - //TODO - }; - - template - using node_BST = node_binary_search_tree; - template - using flat_binary_search_tree = heap; - template - using flat_BST = flat_binary_search_tree; } diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt deleted file mode 100644 index a699ad8..0000000 --- a/tests/CMakeLists.txt +++ /dev/null @@ -1,36 +0,0 @@ -cmake_minimum_required(VERSION 3.1) -project(BLT_TESTS) -include(CTest) - -option(ENABLE_ADDRSAN "Enable the address sanitizer" ON) -option(ENABLE_UBSAN "Enable the ub sanitizer" ON) -option(ENABLE_TSAN "Enable the thread data race sanitizer" OFF) - -set(CMAKE_CXX_STANDARD 17) - -include_directories(include/) -file(GLOB_RECURSE PROJECT_BUILD_FILES "${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp") - -add_executable(${PROJECT_NAME} ${PROJECT_BUILD_FILES}) - -message("Created Tests, Linking BLT") - -target_link_libraries(${PROJECT_NAME} BLT) - -target_compile_options(${PROJECT_NAME} PRIVATE -Wall -Werror -Wpedantic -Wno-comment) -target_link_options(${PROJECT_NAME} PRIVATE -Wall -Werror -Wpedantic -Wno-comment) - -if (${ENABLE_ADDRSAN} MATCHES ON) - target_compile_options(${PROJECT_NAME} PRIVATE -fsanitize=address) - target_link_options(${PROJECT_NAME} PRIVATE -fsanitize=address) -endif () - -if (${ENABLE_UBSAN} MATCHES ON) - target_compile_options(${PROJECT_NAME} PRIVATE -fsanitize=undefined) - target_link_options(${PROJECT_NAME} PRIVATE -fsanitize=undefined) -endif () - -if (${ENABLE_TSAN} MATCHES ON) - target_compile_options(${PROJECT_NAME} PRIVATE -fsanitize=thread) - target_link_options(${PROJECT_NAME} PRIVATE -fsanitize=thread) -endif () \ No newline at end of file