从BinaryTree中删除BinaryTreeNode

时间:2011-10-30 10:45:49

标签: c++ memory-management tree binary-tree

我有一个BinarySearchTree由节点组成,这些节点都是dataType student的模板类,其中student是一个具有名称和等级的私有变量的类。

目前我可以打印树,在树中查找名称和/或等级,但是我在从树中删除节点时遇到了问题。

我正在尝试删除所有具有等级< 50(失败了)。

删除节点后,需要执行以下操作之一:

  1. 左子项为空:用正确的子项替换节点。
  2. 左子项不为空:用左侧的最高元素替换节点 分支。
  3. 我对此的理解是,如果这是树:

          1
         /  \
        2    3
       / \   /\
      4  5  6  7
    

    如果2失败,即等级<1。 50

    你最终会得到

         1
        /  \
      4     3
       \    / \
        5  6  7
    

    4是左分支中的最高元素。

    如果这是树:

         1
        /  \
       2     3
       \     / \
        5  6   7
    

    和2失败

    你最终会得到

         1
        /  \
      5      3
            /  \
           6   7
    

    如果这是树:

         1
        /  \
      2     3
     / \    / \
     4  5  6  7
    

    且1次失败

    你最终会得到

         5
        /  \
      2     3
     /      / \
    4      6  7
    

    我在尝试创建函数时遇到了很多麻烦,目前我已经:

    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;
    }
    }
    

    现在我正在尝试添加deleteNode功能,我只是坚持做什么/处理需要发生的事情:

    void deleteNode(BTNode<Student> *parentNode, bool left)
    {
    BTNode<Student>* nodeToDelete;
    
    if (left)
    {
        nodeToDelete = parentNode->getLeft();
    }
    }
    

2 个答案:

答案 0 :(得分:1)

我设法用这个来实现它:

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;
    }
}
}

答案 1 :(得分:0)

首先,您的checkBranch有点不对劲。如果根节点无效会发生什么?它不会被删除。我建议使用一种更喜欢这种方式的回调方法:

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);
}

对于delete实施检查here,其中find == true。注意:此代码未经过测试。