繁体   English   中英

如何使用递归删除二进制搜索树中的节点

[英]How to delete a node in a binary search tree using recursion

现在,我一直在尝试制定一种删除函数,以删除二进制搜索树中的节点,因为该节点包含要搜索的内容。 我已经为搜索内容的函数编写了框架,并根据是否找到内容返回true或false。 问题是我似乎无法了解如何为我的功能实现实际的删除部分。 如果根节点包含我要查找的值,则我不知道如何在删除后为旧根子节点之一分配根位置。 我也很难弄清楚删除节点后如何将子指针变为NULL并重新链接树的某些部分,如果我只是断开包含要搜索的值的节点,则可能会被切断。

下面是我到目前为止拥有的功能:

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;
}

删除节点的一​​种可能方法是用其直接后继节点替换它或删除叶子,以免破坏树的不变性。

节点的后继者是其右子树的最左子节点,因此一旦到达要删除的节点,请搜索后继者并交换节点。 完成后,搜索叶子并将其删除。 当您选择最左边的孩子时,您确定叶子将具有NULL左边的孩子。 它有一个合适的孩子,用合适的孩子替换叶子,就是这样。

用于二分搜索树的通常实现是使Remove返回一个Node,因此您可以仅通过返回节点来重塑该树的形状,而不必为子孙案例打扰。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM