Two children delete is still broken. Single / no child delete works fine.

v1
Brett 2023-01-12 14:09:34 -05:00
parent 89f77e3aa9
commit 4b89ec2ee1
3 changed files with 54 additions and 50 deletions

4
build_and_run_debug.sh Executable file
View File

@ -0,0 +1,4 @@
#!/bin/bash
cd cmake-build-debug
cmake -DBUILD_TESTS=ON -G Ninja ../ && ninja -j 16 && ./BLT_TESTS
cd ..

View File

@ -134,7 +134,6 @@ namespace blt {
} }
return root; return root;
} }
public: public:
node_binary_search_tree() = default; node_binary_search_tree() = default;
@ -153,58 +152,56 @@ namespace blt {
void remove(const T& element) { void remove(const T& element) {
BST_node* parent = nullptr; BST_node* parent = nullptr;
BST_node* elementNode = search(&parent, element); BST_node* elementNode = search(&parent, element);
if (parent == elementNode)
BST_node*& parentChildSide = parent->left; parent = nullptr;
if (parent->right == elementNode)
parentChildSide = parent->right;
if (elementNode->left != nullptr && elementNode->right != nullptr) { if (elementNode->left != nullptr && elementNode->right != nullptr) {
// root node special case: TODO: better way of doing this. BST_node* inOrderSuccessor = elementNode->left != nullptr ? elementNode->left : elementNode->right;
/*auto& leastNodeGreater = findMin(elementNode->right); BST_node* inOrderSuccessorParent = nullptr;
if (parent != elementNode) { // go all the way to the left subtree
// move up the node and delete the old one. while (inOrderSuccessor->left != nullptr) {
parentChildSide->payload = leastNodeGreater->payload; inOrderSuccessorParent = inOrderSuccessor;
if (leastNodeGreater->parent->left == leastNodeGreater) inOrderSuccessor = inOrderSuccessor->left;
leastNodeGreater->parent->left = nullptr; }
else // make sure we maintain the tree structure if our moving node has a subtree
leastNodeGreater->parent->right = nullptr; BST_node* inOrderSuccessorReplacement = inOrderSuccessor->right != nullptr ? inOrderSuccessor->right : nullptr;
delete(leastNodeGreater);
} else {
leastNodeGreater->left =
}*/
/* delete(m_root);
m_root = nullptr;
// reconstruct subtree. More efficient way of doing this... TODO
std::vector<BST_node*> subNodes = inOrderTraverse(elementNode);
for (auto* node : subNodes) {
// insert will create a new node, we must delete old one to prevent memory leaks
if (node != elementNode) {
insert(node->payload);
delete (node);
}
}
} else {
// reconstruct subtree. More efficient way of doing this... TODO
std::vector<BST_node*> subNodes = inOrderTraverse(elementNode);
for (auto* node : subNodes) {
// insert will create a new node, we must delete old one to prevent memory leaks
if (node != elementNode) {
insert(parent, node->payload);
delete (node);
}
}
}*/
} else {
parentChildSide = elementNode->left != nullptr ? elementNode->left : elementNode->right;
}
std::cout << elementNode << "\n";
//delete (elementNode);
if (parent != nullptr) {
if (parent->right == elementNode)
parent->right = inOrderSuccessor;
else if (parent->left == elementNode)
parent->left = inOrderSuccessor;
else
throw binary_search_tree_error("Parent node doesn't own child!\n");
} else
m_root = inOrderSuccessor;
// reconstruct the node's children
inOrderSuccessor->left = elementNode->left;
inOrderSuccessor->right = elementNode->right;
// delete the parent's reference to the moved node
if (inOrderSuccessorParent != nullptr){
if (inOrderSuccessorParent->left == inOrderSuccessor)
inOrderSuccessorParent->left = inOrderSuccessorReplacement;
else if (inOrderSuccessorParent->right == inOrderSuccessor)
inOrderSuccessorParent->right = inOrderSuccessorReplacement;
else
throw binary_search_tree_error("Parent does not contain child!\n");
}
} 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);
} }
/*void remove(const T& element) {
remove(m_root, element);
}*/
inline std::vector<BST_node*> inOrderTraverse() { inline std::vector<BST_node*> inOrderTraverse() {
return inOrderTraverse(m_root); return inOrderTraverse(m_root);

View File

@ -32,9 +32,12 @@ void binaryTreeTest(){
auto searchedNode = dataTree.search(10); auto searchedNode = dataTree.search(10);
std::cout << "10's children: "<< searchedNode->left->payload << ", " << searchedNode->right->payload << "\n"; std::cout << "10's children: "<< searchedNode->left->payload << ", " << searchedNode->right->payload << "\n";
dataTree.remove(4); dataTree.remove(10);
printBinaryTree(dataTree); printBinaryTree(dataTree);
//searchedNode = dataTree.search(8);
//std::cout << "8's children: "<< searchedNode->left->payload << ", " << searchedNode->right->payload << "\n";
} }