我正在研究一个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;
并且temp指针正在我不熟悉的行为中运行,或者我的整个实现是错误的。我知道丢失的节点在某处,因为我的内存泄漏显示我丢失的那两个节点永远不会被删除。
答案 0 :(得分:2)
我想知道它是否与行
有关
是。 Node<ItemType>* & temp = node->rightChild;
说temp
是node->rightChild
的别名。因此,while
循环会修改node->rightChild
,并且您将丢失原始右侧孩子的句柄。
取一个普通的指针,然后沿着右边的子树向下走,直到你找到它最小的成员的父节点。然后获取最小成员的值,将其复制到node->item
,并删除父级的左子。