Reputation: 3887
I have a BinarySearchTree
that consists of nodes which are both a template class of dataType student, where student is a class with private variables of name and grade.
At the moment I can print the tree, find names and or grades in the tree but I am having trouble deleting nodes from the tree.
I am trying to delete all students who had a grade < 50 (so failed).
Once a node is deleted one of the following needs to occur:
My understanding of this is, if this was the tree:
1
/ \
2 3
/ \ /\
4 5 6 7
If 2 failed i.e. had a grade < 50
You would end up with
1
/ \
4 3
\ / \
5 6 7
4 being the highest element in the left branch.
If this was the tree:
1
/ \
2 3
\ / \
5 6 7
and 2 failed
you would end up with
1
/ \
5 3
/ \
6 7
If this was the tree:
1
/ \
2 3
/ \ / \
4 5 6 7
and 1 failed
you would end up with
5
/ \
2 3
/ / \
4 6 7
I have been having a lot of trouble trying to create functions to do this, at the moment I have:
void checkBranch() //called from main - used to pass the root node to checkBranch()
{
checkBranch(studentTree.getRoot());
}
bool checkBranch(BTNode<Student>* currentNode)
{
if (currentNode != NULL)
{
if (checkBranch(currentNode -> getLeft()))
{
deleteNode(currentNode, true);
}
if (checkBranch(currentNode -> getRight()))
{
deleteNode(currentNode, false);
}
return (currentNode -> getData().getGrade() < 50.0);
}
else
{
return false;
}
}
Now I am trying to add the deleteNode
function where I am just stuck on what to do / handle what needs to occur:
void deleteNode(BTNode<Student> *parentNode, bool left)
{
BTNode<Student>* nodeToDelete;
if (left)
{
nodeToDelete = parentNode->getLeft();
}
}
Upvotes: 6
Views: 5519
Reputation: 10940
First, your checkBranch
is kind of wrong. What happens if the root node is invalid? It will not be deleted. I suggest a more elegant way here using a callback approach that could like this:
int deleteNodesOnCondition(BTNode<Student>* node, bool(* condition)(BTNode<Student>*))
{
int deleteCount = -1;
if(condition != NULL)
{
deleteCount = 0;
if(node != NULL)
{
deleteCount += deleteNodesOnCondition(node->getLeft(), condition);
deleteCount += deleteNodesOnCondition(node->getRight(), condition);
bool satisfied = condition(node);
if(satified)
{
deleteNode(node);
deleteCount += 1;
}
}
}
return deleteCount;
}
bool checkValidGrade(BTNode<Student> *node)
{
return node != NULL && node->getData().getGrade() >= 50.0;
}
void checkBranch()
{
deleteNodesOnCondition(studentTree.getRoot(), checkValidGrade);
}
For the delete
implementation check here where found == true. Note: this code is not tested.
Upvotes: 0
Reputation: 3887
I managed to achieve it with this:
template <typename dataType>
void BTree<dataType>::deleteNode(BTNode<dataType> *parentNode, bool left)
{
BTNode<dataType> *nodeToDelete;
BTNode<dataType> *currentNode;
if (left)
{
nodeToDelete = parentNode->getLeft();
}
else
{
nodeToDelete = parentNode->getRight();
}
if (nodeToDelete->getLeft() == NULL)
{
currentNode = nodeToDelete;
if (left)
{
parentNode->setLeft(nodeToDelete->getRight());
}
else
{
parentNode->setRight(nodeToDelete->getRight());
}
delete nodeToDelete;
}
else
{
BTNode<dataType>* greatestNode = nodeToDelete->getLeft();
if (greatestNode->getRight() == NULL)
{
nodeToDelete->getLeft()->setRight(nodeToDelete->getRight());
if (left)
{
parentNode->setLeft(nodeToDelete->getLeft());
}
else
{
parentNode->setRight(nodeToDelete->getLeft());
}
}
else
{
while (greatestNode->getRight()->getRight())
{
greatestNode = greatestNode->getRight();
}
nodeToDelete->setData(greatestNode->getRight()->getData());
BTNode<dataType> *nodeToDelete2 = greatestNode->getRight();
greatestNode->setRight(greatestNode->getRight()->getLeft());
delete nodeToDelete2;
}
}
}
Upvotes: 1