[英]Binary tree: method remove subtree
我有一个无序的二叉树,我不得不做一个删除根x的子树的方法。 如果元素x在二叉树中多次出现,则该方法仅删除根x中的一个子树(它找到的第一个子树)。 如果执行了删除,则返回true。 如果元素x不存在于二叉树中,则返回false。 所以方法是:
public class BinaryTree
{
protected class Node
{
Integer element;
Node left;
Node right;
Node(int element)
{
this.element = element;
left = right = null;
}
Node(int element, Node left, Node right)
{
this.element = element;
this.left = left;
this.right = right;
}
protected Node root;
public BinaryTree()
{
root = null;
}
private class BoolNode
{
boolean ft;
Node nodo;
BoolNode(boolean ft, Node nodo)
{
this.ft = ft;
this.nodo = nodo;
}
}
public boolean removeSubtree(int x)
{
BoolNode ris = removeSubtree(x, root);
//root = ...;
return ris.ft;
}
private BoolNode removeSubtree(int x, Node node)
{
return null;
}
}
我不知道如何开始,有没有人有任何想法? 甚至伪代码..谢谢!
应该像这样......
如果N是父母,
removeNodes(N.left); removeNodes(N.right); remove(N);
重复,直到你击中一片叶子
private void removeNodes(Node base); //prepare for this when the teacher asks you why it's private // - because you do not want to expose this functionality outside of the class; // the only 'interface' exposed is the wrapper call removeSubtree(...) as the user shouldn't worry about the internal functionality.
removeSubtree()是递归removeNodes()的包装器;
编辑:好的,以澄清你的错误。 假设我们有这棵树
1 --- this is root
/ \
3 7
/ \ / \
(a) 5 4 3 2 //these branches don't matter right now
/ \
5 6
/ \ / \
5 4 3 2
现在,假设你调用removeSubtree(5,root);
它将遍历树,直到它到达节点(a) - 左边的前5个。 编写当前代码的方式是:它将找到值为X(5)的节点; 然后,对于他所有的左右子孙,它将寻找值5。
让我们关注这一点
1 --- this is root
/ \
3 7
\ / \
4 3 2
这是调用removeSubtree(5,root)后应该得到的; 换句话说,查找在找到值为5的第一个节点并删除它的子节点后应该删除的子树
5 -- we should delete all of these starting from here
/ \
5 6
/ \ / \
5 4 3 2
但是,您的代码随后会在该子树中查找要删除的值5。 这就是为什么你需要一个通用的deleteSubtree()例程,它将遍历树并删除它找到的所有内容。 您的removeSubtree(int,node)例程必须通过实现该机制本身来依赖它或“内联”它。
现在你的代码只会删除它
1 --- this is root
/ \
3 7
/ \ / \
(a) 5 4 3 2 //these branches don't matter right now
/ \
(b) 5 6
/ \ / \
(c) 5 4 3 2
换句话说,它将落在节点A(前5),而不是删除节点(a)下面的所有内容,它将搜索低于A的另一个值5,找到(b)并尝试删除它的子树,仅匹配节点(C)。
最终结果将是这样 - 您的代码将只删除三个五,并留下你
1 --- this is root
/ \
3 7
/ \ / \
x 4 3 2
/ \
x 6
/ \ / \
x 4 3 2
你现在意识到为什么你不能递归使用相同的功能? :)至少不是你现在想要的方式。 但是,你可以尝试这个 -
removeSubtree(node.left.value, node);
removeSubtree(node.right.value, node);
removeNode(node);
这将有效地找到正确的子树 - 节点(a),然后调用自身以匹配它的子节点 - 节点5和6(节点(b)的深度),从而删除它们。 在任何情况下,您都不能像以前那样在这些调用中重复使用值X.
removeSubtree(x, node.left);
removeSubtree(x, node.right);
removeNode(node);
我希望澄清一些东西:)嘿,也许我应该教这个:D
private BoolNode removeSubtree(Node node, int x)
{
if(node == null)
return new BoolNode(false, null);
if(node.element == x)
return new BoolNode(true, null);
BoolNode result = removeSubtree(node.left, x);
if(result.fatto)
node.left = null;
else {
result = removeSubtree(node.right, x);
node.right = null;
}
return new BoolNode(result.fatto, node);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.