我一直在尝试为二进制搜索树实现删除功能,但无法在所有情况下都能使用它。
这是我最近的尝试:
Node* RBT::BST_remove(int c)
{
Node* t = get_node(c);
Node* temp = t;
if(t->get_left() == empty)
*t = *t->get_left();
else if(t->get_right() == empty)
*t = *t->get_right();
else if((t->get_left() != empty) && (t->get_right() != empty))
{
Node* node = new Node(t->get_data(), t->get_parent(), t->get_colour(), t->get_left(), t->get_right());
*t = *node;
}
return temp;
}
Node* RBT::get_node(int c)
{
Node* pos = root;
while(pos != empty)
{
if(c < pos->get_data())
pos = pos->get_left();
else if(c == pos->get_data())
return pos;
else
pos = pos->get_right();
}
return NULL;
}
t是一个节点,而空是一个没有任何内容的节点。
我只是尝试交换值但是我遇到了运行时错误。有什么想法吗?
编辑:之后我会回复删除它。
由于
答案 0 :(得分:3)
首先,您的上一个else if
条件子句是多余的。用else
子句交换它。
其次,如果您将参数指向要删除的节点,我认为它会让您更轻松。您可以编写一个find()
函数,该函数可以找到给定其密钥的节点。我当然假设您可以更改功能签名。如果您可以将要删除的节点作为参数,则可以专注于删除节点,而不是添加用于查找节点的逻辑。否则,仍然写入find()
函数并使用它来获取指向相关节点的指针。
删除二叉搜索树中的节点时,必须保持顺序,以便树不会失去其完整性。回想一下,树中有一个支持快速检索元素的特定顺序。因此,列举可能的案例:
D
。找到D
左子树的最右边的孩子。我们称这个节点为R
。将R
的值分配给D
,然后删除R
(如此算法中所述)。请注意,R
可以有零个或一个孩子。第三种情况,说明:
.
.
.
/
D
/ \
/\ .
/ \
/ \
+------+
\
R
/
?