[英]recursive delete on a binary tree
我試圖理解刪除二叉搜索樹的遞歸方法是如何工作的。 我在許多地方遇到的代碼如下所示:
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->左)。 因此,leaf if if為NULL,並且if-dependent不執行,因此5不被刪除。 我在哪里弄錯了這個推理? 如何在這里進行卷繞和退繞? 任何幫助都很感激:-)
在那一點看起來像這樣:
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)
......等等......
這是函數基本上如何工作:
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;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.