简体   繁体   English

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

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

I have now been trying to formulate a deletion function for deleting a node inside a binary search tree given that the node contains the content being searched for. 现在,我一直在尝试制定一种删除函数,以删除二进制搜索树中的节点,因为该节点包含要搜索的内容。 I have wrote the skeleton for the function that does the search for the content and returns true or false depending on if it found it or not. 我已经为搜索内容的函数编写了框架,并根据是否找到内容返回true或false。 The issue is that I cannot seem to get how to implement the actual deletion part for my function. 问题是我似乎无法了解如何为我的功能实现实际的删除部分。 If the root node contains the value I am looking for, I do not know how to assign one of the old root's children the root position after deletion. 如果根节点包含我要查找的值,则我不知道如何在删除后为旧根子节点之一分配根位置。 I am also having a hard time figuring out how to NULL the children pointers after deletion of a node and relinking parts of the tree that could potentially be severed if I just disconnect the node that contains the value being searched. 我也很难弄清楚删除节点后如何将子指针变为NULL并重新链接树的某些部分,如果我只是断开包含要搜索的值的节点,则可能会被切断。

Below is the function I have so far: 下面是我到目前为止拥有的功能:

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

What I have added: 我添加了什么:

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

Helper function for the remove function: 删除功能的辅助功能:

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

One possible way of deleting a node is to replace it with his direct successor the delete the leaf, so that you do not break the tree invariant. 删除节点的一​​种可能方法是用其直接后继节点替换它或删除叶子,以免破坏树的不变性。

The successor of a node is the leftmost child of its right subtree, so once you get to the node you want to delete, search for the successor and swap the nodes. 节点的后继者是其右子树的最左子节点,因此一旦到达要删除的节点,请搜索后继者并交换节点。 Once it's done, search for the leaf and removes it. 完成后,搜索叶子并将其删除。 As you took the leftmost child, you are sure that the leaf will have a NULL left child. 当您选择最左边的孩子时,您确定叶子将具有NULL左边的孩子。 It It has a right child, replace the leaf with the right child and that's it. 它有一个合适的孩子,用合适的孩子替换叶子,就是这样。

A usual implementation used for binary search tree is to make Remove return a Node, so you can reshape the tree just by returning the nodes, and don't have to bother with grandchildren cases. 用于二分搜索树的通常实现是使Remove返回一个Node,因此您可以仅通过返回节点来重塑该树的形状,而不必为子孙案例打扰。

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

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