私はAVLツリーに取り組んでいます。私の削除は、時々正しく機能するようです。こんな感じの木を作りました
f
/ \
e j
/ / \
a h s
を順番に挿入してf e h s j a
ください。インサートとバランシングで正しく機能していることはわかっています。
a
、またはj
、またはh
、またはs
、またはを削除するとe
、すべて正常に動作します。を削除するf
と、 に置き換えf
られh
ます。これは正しいのですが、 と を失いj
ますs
。
これは、最初に呼び出される関数です。
void remove(const ItemType& item)
{
if(root == NULL)
return;
else
{
remove(root, item);
}
};
最初の関数はこれを呼び出して、正しいノードを再帰的に見つけます。
void remove(Node<ItemType>* & node, const ItemType& item)
{
if(item > node->item)
{
if (node->rightChild == NULL)
{
return; // there is nothing here to remove
}
else
{
// recurse to next node
remove(node->rightChild, item);
}
}
else if (item < node->item)
{
if (node->leftChild == NULL)
{
return; // there is nothing here to remove
}
else
{
// recurse to next node
remove(node->leftChild, item);
}
}
else if (node->item == item)
{
remove(node);
}
if (node != NULL)
node->updateHeight();
};
これは最後に呼び出される関数です。これは、削除とスワップが行われる場所です。
void remove(Node<ItemType>* & node)
{
if (node->rightChild == NULL && node->leftChild == NULL)
{
delete node;
node = NULL;
}
else if (node->rightChild == NULL)
{
Node<ItemType>* temp = node;
node = node->leftChild;
delete temp;
}
else
{
Node<ItemType>* & temp = node->rightChild;
while (temp->leftChild != NULL)
temp = temp->leftChild;
node->item = temp->item;
delete temp;
temp = NULL;
}
if(node != NULL)
node->initializeHeight();
};
ラインと関係あるのか気になる
Node<ItemType>* & temp = node->rightChild;
while (temp->leftChild != NULL)
temp = temp->leftChild;
node->item = temp->item;
delete temp;
temp = NULL;
一時ポインタがよくわからない動作をしている、または実装全体が間違っている場合。行方不明になった 2 つのノードが決して削除されないことをメモリ リークが示しているため、行方不明のノードがどこかにあることはわかっています。