我现在一直在尝试制定一个删除函数,用于删除二进制搜索树中的节点,前提是该节点包含要搜索的内容。我已经为搜索内容的函数编写了骨架,并根据它是否找到它返回true或false。问题是我似乎无法获得如何为我的函数实现实际的删除部分。如果根节点包含我正在寻找的值,我不知道如何在删除后为其中一个旧根的子节点指定根位置。在删除节点并重新链接可能被切断的树的部分时,如果我只是断开包含被搜索值的节点,我也很难弄清楚如何将子指针置空。
以下是我到目前为止的功能:
bool BSTree::Remove(int content, BSTNode*& bst_node) const {
// makes sure the tree is not empty (function returns false if it is)
if (bst_node != NULL) {
// checks to see if nodes contents matches content param
if (bst_node->GetContents() == content) {
// checks to see if the node has children
if (bst_node->GetLeftChild() == NULL && bst_node->GetRightChild() == NULL) {
} else if (bst_node->GetLeftChild() == NULL) {
} else if (bst_node->GetRightChild() == NULL) {
} else {
}
return true;
// checks to see if the content of node is less/greater than content param
} else if (content < bst_node->GetContents()) {
if (bst_node->GetLeftChild() != NULL)
return Remove(content, bst_node->GetLeftChild());
} else if (content > bst_node->GetContents()) {
if (bst_node->GetRightChild() != NULL)
return Remove(content, bst_node->GetRightChild());
}
}
return false;
}
我添加了什么:
bool BSTree::Remove(int content, BSTNode*& bst_node) {
BSTNode* parent = bst_node;
if (bst_node == NULL) {
return false;
} else {
if (content == bst_node->GetContents()) {
if (bst_node->GetLeftChild() == NULL && bst_node->GetRightChild() == NULL) {
if (bst_node == root_) {
Clear();
} else {
// code for deleting leaf
bst_node->SetContents(0);
bst_node = NULL;
delete bst_node;
size_--;
}
} else if (bst_node->GetLeftChild() == NULL) {
// code for deleting node with only right child
if (bst_node == root_) {
parent = bst_node->GetRightChild();
bst_node->SetContents(0);
bst_node = NULL;
delete bst_node;
root_ = parent;
} else {
}
size_--;
} else if (bst_node->GetRightChild() == NULL) {
// code for deleting node with only left child
if (bst_node == root_) {
parent = bst_node->GetLeftChild();
bst_node->SetContents(0);
bst_node = NULL;
delete bst_node;
root_ = parent;
} else {
}
size_--;
} else {
// code for deleting node with two children
size_--;
}
} else if (content < bst_node->GetContents()) {
if (bst_node->GetLeftChild() == NULL) {
return false;
} else {
return Remove(content, bst_node->GetLeftChild());
}
} else if (content > bst_node->GetContents()) {
if (bst_node->GetRightChild() == NULL) {
return false;
} else {
return Remove(content, bst_node->GetRightChild());
}
}
}
return true;
}
删除功能的助手功能:
int BSTree::FindMin(BSTNode* bst_node) const {
if (bst_node != NULL) {
if (bst_node->GetLeftChild() != NULL)
return FindMin(bst_node->GetLeftChild());
return bst_node->GetContents();
}
return 0;
}
答案 0 :(得分:0)
删除节点的一种可能方法是将其替换为直接后继者删除叶子,这样就不会破坏树的不变性。
节点的后继节点是其右子树的最左边的子节点,因此一旦到达要删除的节点,搜索后继节点并交换节点。完成后,搜索叶子并将其删除。当您占据最左边的孩子时,您确定该叶子将有一个NULL左子。它有一个正确的孩子,用正确的孩子取代叶子,就是这样。
用于二叉搜索树的通常实现是使Remove
返回一个节点,因此您只需返回节点就可以重塑树,而不必为孙子案件打扰。