Я создал класс двоичного дерева поиска (узла):
class BstNode {
public:
BstNode(int value);
~BstNode();
BstNode* Delete(int value);
// more methods
private:
int value_;
BstNode* left_;
BstNode* right_;
};
С деструктором, который выглядит следующим образом:
BstNode::~BstNode() {
delete left_;
delete right_;
}
А Delete
функция:
BstNode* BstNode::Delete(int value) {
// If the value to be deleted is smaller than the root's key,
// then it lies in the left subtree.
if (value < value_) {
if (left_ == nullptr) return nullptr;
else left_ = left_->Delete(value);
}
// If the value to be deleted is larger than the root's key,
// then it lies in the right subtree.
else if (value > value_) {
if (right_ == nullptr) return nullptr;
else right_ = right_->Delete(value);
}
// If the key to be deleted is the same as root's key, then *this*
// is the node to be deleted.
else {
// If this node has no children, then we can just delete it.
if (left_ == nullptr && right_ == nullptr) {
delete this;
return nullptr;
}
// If this node has one child, then we can just set this node to
// that child and delete this node afterwards.
else if (left_ == nullptr) {
BstNode* temp = right_;
delete this;
return temp;
}
else if (right_ == nullptr) {
BstNode* temp = left_;
delete this;
return temp;
}
// If this node has two children, then we have to get the "in-order successor"
// (the smallest node in the right subtree).
else {
BstNode *temp = right_->Smallest();
// Copy that node's value to this node
value_ = temp->value_;
// Then delete that value from the right subtree
right_ = right_->Delete(value_);
}
}
return this;
}
Что меня смущает, так это фрагмент:
else if (left_ == nullptr) {
BstNode* temp = right_;
delete this;
return temp;
}
else if (right_ == nullptr) {
BstNode* temp = left_;
delete this;
return temp;
}
Если вызов delete
вызывает деструктор класса, разве я не удалил бы все поддерево (правое или левое)? Однако при тестировании создается впечатление, что дерево делает именно то, что мне нужно: удалить узел и «переместить» дочернее поддерево туда, где находится «это», при этом поддеревья все еще не повреждены.
Выполнение BstNode* temp = this;
, насколько мне известно, просто скопирует указатели на left_
и right_
, а затем вызов delete this
должен уничтожить данные, стоящие за ними.
Я что-то упускаю из delete this
?