这让我疯了。我创建了一个二进制搜索树类,其功能类似于集合,自动平衡数字等,每个节点都有三个值,left
和right
指针以及T data
。除了删除方法之外,我已经完成了所有工作,并且出于某种原因它实际上并没有删除...没有段错误或任何东西。在类中构建了一个析构函数,我测试了它。我究竟做错了什么?这是remove方法及其使用的方法。
template < class T >
void binSTree< T >::remove( Node < T >*& passedNode, const T& targetValue )
{
if( passedNode->data == targetValue ) //if the passed node is the target value
{
if ( passedNode->left == NULL && passedNode->right == NULL ) //if it has no children at all
{
Node < T >* parentNode = parent( passedNode);
if( parentNode->left == passedNode )
parentNode->left = NULL;
else
parentNode->right = NULL;
delete passedNode; //simply delete it, it won't be missed
return;
}
else if ( passedNode->left == NULL && passedNode->right != NULL ) //otherwise if it has left children
{
popout( passedNode, passedNode->left ); //connect previous node with left and remove current
return;
}
else if ( passedNode->left != NULL && passedNode->right == NULL ) //otherwise if it has right children
{
popout( passedNode, passedNode->right ); //connect previous node with right and remove current
return;
}
else if ( passedNode->left != NULL && passedNode->right != NULL ) //otherwise if it has both children
{
//now we have to find the closest lower value, i.e. the rightmost value to the left
Node < T >* currentNode = pred( passedNode ); //start with the left child
passedNode->data = currentNode->data; //set the value of our original node to the current one we are on
popout( currentNode, currentNode->right ); //bypass and delete the current node
}
}
}
template < class T >
Node < T >* binSTree< T >::pred( Node < T >* passedNode)
{
if( passedNode->left == NULL ) //if it has no left childen,
return parent( passedNode ); //then the next lowest number is its parent
else
{
Node < T >* currentNode = passedNode->left; //make an iterator and move left
while( currentNode->right != NULL )
currentNode = currentNode->right; //then move right until leaf
return currentNode;
}
}
template < class T >
Node < T >* binSTree< T >::parent( Node < T >* passedNode)
{
Node < T >* currentNode = passedNode;
while( currentNode->left != NULL && currentNode->right != NULL ) //while we are not yet at a leaf
{
if( currentNode->left == passedNode || currentNode->right == passedNode ) //if either child is it
return currentNode; //return the current value
else if( passedNode->data < currentNode->data ) //otherwise if the passedNode is less than where we are
currentNode = currentNode->left; //turn left
else //if the passedNode is greater than where we are
currentNode = currentNode->right;
}
cerr << "No parent detected for node with value " << passedNode->data << endl;
//print an error hear if it ended the loop
}
template < class T >
void binSTree< T >::popout( Node < T >*& targetNode, Node < T >*& childNode )
{
Node < T >* parentNode = parent( targetNode ); //set the parent
if( parentNode->left == targetNode ) //if the left matches our target node
parentNode->left = childNode; //replace it with the childNode
else if( parentNode->right == targetNode ) //if the right matches our target node
parentNode->right = childNode; //replace it with the child node
else //this is only done if for some reason the target is neither child
cerr << "An error occurred, parent/target mismatch for parent with value "
<< parentNode->data << " and target with value " << targetNode->data << endl;
delete targetNode; //now that it has been bypassed, delete the target
}