所以我用C ++实现了一个AVL。 当我测试树函数时,当我尝试执行以下操作时,特定测试失败:
将100插入树中 **现在树应该是这样的:
100(root)
60
从树中删除60
**我们期望发生的事情:
60(root)
但相反,我得到一个段错误。 此外,当我尝试删除100,一切都很好! 这些是被调用的方法:
void AVL<T, Compare>::Delete(const T& key) {
Node<T>* node = find(key);
if (!node) {
return;
}
Node<T>* parent = node->getParent();
if (node->isLeaf() == 1) {
leafRemove(node);
fixBalance(parent);
} else {
if ((node->getRight()) && (node->getLeft())) {
oneChildRemove(node);
} else {
twoChildrenRemove(node);
}
}
}
加:
void AVL<T, Compare>::twoChildrenRemove(Node<T>* node) {
Node<T>* swapped = getNodeSuccessor(node);
Node<T>* ancestor = node->getParent();
swapNodes(node, swapped);
if (!(swapped->getLeft()) && (!swapped->getRight())) {
leafRemove(swapped);
} else {
oneChildRemove(swapped);
}
if (!ancestor) {
fixBalance(node);
} else {
fixBalance(ancestor);
}
return;
}
和
template<class T, class Compare>
void AVL<T, Compare>::oneChildRemove(Node<T>* node) {
Node<T>* ancestor = node->getParent(); //=100
Node<T>* branch;
if (node->getLeft()) {
branch = node->getLeft();
}
if (node->getRight()) {
branch = node->getRight();
}
swapNodes(node, branch);
leafRemove(branch);
if (!ancestor) {
fixBalance(node);
} else {
fixBalance(ancestor);
}
}
你能发现问题吗?
答案 0 :(得分:1)
您对AVL Tree的理解是错误的。
删除节点时,您的算法应满足以下条件,
1) If x has no children, delete x.
2) If x has one child, delete x and link x's parent to x's child
3) If x has two children,
-find x's successor z [the leftmost node in the rightsubtree of x]
-replace x's contents with z's contents, and
-delete z.
(Note: z does not have a left child, but may have a right child)
[since z has at most one child, so we use case (1) or (2) to delete z]
我会告诉你这个概念,然后你从那里发展。
void AVL<T, Compare>::oneChildRemove(Node<T>* node) {
Node<T>* swapped= node->getNodeSuccessor(node); //Get the only child
Node<T>* ancestor = node->getParent();
swapNodes(ancestor, swapped); //copy child node(swapped) to point to parent(ancestor)
leafRemove(node);//Delete the node child
}
void AVL<T, Compare>::twoChildrenRemove(Node<T>* node) {
Node<T>* ancestor = node->getParent();//Get Parent Node of the node to be deleted.
Node<T>* rightChild = getRightSuccessor(node);//Get Right Child of the node to be deleted
Node<T>* leftMostRigthChild = GetLeftMostRightChild(rightChild);//Get Left most child of the right child.
swapNodes(leftMostRigthChild , ancestor);//copy leftmostrightchild to point to parent
if (!leftMostRigthChild ->getRight()) { //If no right child for the leftMostRigthChild its leaf node.
leafRemove(leftMostRigthChild); //So delete it.
} else {
oneChildRemove(leftMostRigthChild); //Else it is have one right child and hence call oneChildRemove for the leftMostRigthChild.
}
return;
}