从BinaryTree中删除BinaryTreeNode

che*_*man 6 c++ tree binary-tree memory-management

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

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

我试图删除所有年级<50(因此失败)的学生.

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

  1. 左子项为空:用正确的子项替换节点.
  2. 左子项不为空:用左分支中的最高元素替换节点.

我对此的理解是,如果这是树:

      1
     /  \
    2    3
   / \   /\
  4  5  6  7
Run Code Online (Sandbox Code Playgroud)

如果2失败,即等级<50

你最终会得到

     1
    /  \
  4     3
   \    / \
    5  6  7
Run Code Online (Sandbox Code Playgroud)

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

如果这是树:

     1
    /  \
   2     3
   \     / \
    5  6   7
Run Code Online (Sandbox Code Playgroud)

2失败了

你最终会得到

     1
    /  \
  5      3
        /  \
       6   7
Run Code Online (Sandbox Code Playgroud)

如果这是树:

     1
    /  \
  2     3
 / \    / \
 4  5  6  7
Run Code Online (Sandbox Code Playgroud)

1失败了

你最终会得到

     5
    /  \
  2     3
 /      / \
4      6  7
Run Code Online (Sandbox Code Playgroud)

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

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;
}
}
Run Code Online (Sandbox Code Playgroud)

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

void deleteNode(BTNode<Student> *parentNode, bool left)
{
BTNode<Student>* nodeToDelete;

if (left)
{
    nodeToDelete = parentNode->getLeft();
}
}
Run Code Online (Sandbox Code Playgroud)

che*_*man 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;
    }
}
}
Run Code Online (Sandbox Code Playgroud)