簡體   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