从BinaryTree中删除BinaryTreeNode
Deleting a BinaryTreeNode from a BinaryTree
我有一个BinarySearchTree
,它由节点组成,这些节点都是数据类型为student的模板类,其中student是一个具有name和grade私有变量的类。
目前我可以打印树,在树中找到名字和/或成绩,但我在从树中删除节点时遇到麻烦。
我试图删除所有有一个等级的学生<50(如此失败)。
一旦一个节点被删除,需要发生以下情况之一:
- 左子节点为空:用其右子节点替换该节点。
- 左子节点不为空:用左边最高的元素替换该节点分支。
我的理解是,如果这是树:
1
/
2 3
/ /
4 5 6 7
如果2不及格,即有一个等级<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();
}
}
我是这样做到的:
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;
}
}
}
首先,你的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
实现,在找到== true的地方检查。注意:此代码未经过测试