【问题标题】:recursive delete on a binary tree二叉树上的递归删除
【发布时间】:2013-06-15 05:02:30
【问题描述】:

我试图了解删除二叉搜索树的递归方法是如何工作的。我在很多地方遇到的代码如下:

void destroy_tree(struct node *leaf)
{
  if( leaf != 0 )
  {
      destroy_tree(leaf->left);
      destroy_tree(leaf->right);
      free( leaf );
  }
}

但是我不明白 a) 如果例程中没有返回,它是如何工作的? b) free() 何时被调用?我想,例如,这样一棵树:

                           10
                         /    \
                        6      14
                       / \    /  \
                      5   8  11  18

所以我的理解是遍历10->6->5,然后调用destroy_tree(5->left)。所以if里面的leaf是NULL,不执行if依赖的,所以5没有被删除。我在这个推理中哪里出错了?卷绕和展开是如何在这里工作的?任何帮助都非常感谢:-)

【问题讨论】:

    标签: c++ c recursion binary-tree binary-search-tree


    【解决方案1】:

    那时看起来像这样:

    void destroy_tree(struct node *leaf_5)
    {
      if( leaf_5 != 0 )  // it's not
      {
          destroy_tree(leaf_5->left); // it's NULL so the call does nothing
          destroy_tree(leaf_5->right); // it's NULL so the call does nothing
          free( leaf_5 );  // free here
      }
    }
    

    不需要返回...步骤的“历史”在调用堆栈上,此时看起来像这样:

    destroy_tree(leaf_10)
      destroy_tree(leaf_10->left, which is leaf_6)
        destroy_tree(leaf_6->left, which is leaf_5)
    

    所以在leaf_5 消失后,它会返回堆栈并执行destroy_tree(leaf_6->right, which is leaf_8)...等...

    【讨论】:

      【解决方案2】:

      这就是函数的基本工作方式:

      void destroy_tree(struct node *leaf)
      {
        if( leaf_5 != 0 )  // it's not
        {
            destroy_tree(leaf->left); 
             // Traverse the tree all the way left before any of the code below gets executed.
            destroy_tree(leaf->right); 
             // Traverse the tree all the way right from the final left node before any of 
             //the code below gets executed
            free( leaf );  // Free the final node
        }
      }
      

      下面是递归删除的完整实现的代码:

      void DeleteNode(TreeNode*& tree);
      void Delete(TreeNode*& tree, ItemType item);
      void TreeType::DeleteItem(ItemType item)
      // Calls the recursive function Delete to delete item from tree.
      {
      Delete(root, item);
      }
      void Delete(TreeNode*& tree, ItemType item)
      // Deletes item from tree.
      // Post: item is not in tree.
      {
      if (item < tree->info)
      Delete(tree->left, item); // Look in left subtree.
      else if (item > tree->info)
      Delete(tree->right, item); // Look in right subtree.
      else
      DeleteNode(tree); // Node found; call DeleteNode.
      }
      
      
      void GetPredecessor(TreeNode* tree, ItemType& data);
      void DeleteNode(TreeNode*& tree)
      // Deletes the node pointed to by tree.
      // Post: The user's data in the node pointed to by tree is no
      // longer in the tree. If tree is a leaf node or has only one
      // non-NULL child pointer, the node pointed to by tree is
      // deleted; otherwise, the user's data is replaced by its
      // logical predecessor and the predecessor's node is deleted.
      {
      ItemType data;
      TreeNode* tempPtr;
      tempPtr = tree;
      if (tree->left == NULL)
      {
      tree = tree->right;
      delete tempPtr;
      }
      else if (tree->right == NULL)
      {
      tree = tree->left;
      delete tempPtr;
      }
      else
      {
      GetPredecessor(tree->left, data);
      tree->info = data;
      Delete(tree->left, data); // Delete predecessor node.
      }
      }
      
      void GetPredecessor(TreeNode* tree, ItemType& data)
      // Sets data to the info member of the rightmost node in tree.
      {
      while (tree->right != NULL)
      tree = tree->right;
      data = tree->info;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2023-04-10
        • 1970-01-01
        • 1970-01-01
        • 2015-04-08
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多