deepseapanda
deepseapanda

Reputation: 3887

Deleting a BinaryTreeNode from a BinaryTree

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:

  1. Left child is empty: Replace the node by its right child.
  2. Left child is not empty: Replace the node by the highest element in the left branch.

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

Answers (2)

esskar
esskar

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

deepseapanda
deepseapanda

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

Related Questions