Recursion 使用递归根据给定的最小值和最大值修剪二叉树
正如标题所说,我必须根据给定的最小值和最大值修剪二叉树。每个节点存储一个值和一个左/右节点。我可以定义私有助手方法来解决这个问题,但是我不能调用该类的任何其他方法,也不能创建任何数据结构,例如数组、列表等 示例如下所示:Recursion 使用递归根据给定的最小值和最大值修剪二叉树,recursion,binary-tree,Recursion,Binary Tree,正如标题所说,我必须根据给定的最小值和最大值修剪二叉树。每个节点存储一个值和一个左/右节点。我可以定义私有助手方法来解决这个问题,但是我不能调用该类的任何其他方法,也不能创建任何数据结构,例如数组、列表等 示例如下所示: overallRoot _____[50]____________________ /
overallRoot
_____[50]____________________
/ \
__________[38] _______________[90]
/ \ /
_[14] [42] [54]_____
/ \ \
[8] [20] [72]
\ / \
[26] [61] [83]
trim(52, 65);
CutBranch(x,T) {
y = T.root;
while (y.left != x && y.right != x) {
if (y < x) y = y.right;
else y = y.left;
}
if (y < x) y.right = Nil;
else y.left = Nil;
}
应返回:
overallRoot
[54]
\
[61]
我尝试的解决方案有三种方法:
public void trim(int min, int max) {
rootFinder(overallRoot, min, max);
}
第一个递归方法完美地找到了新的根
private void rootFinder(IntTreeNode node, int min, int max) {
if (node == null)
return;
if (overallRoot.data < min) {
node = overallRoot = node.right;
rootFinder(node, min, max);
}
else if (overallRoot.data > max) {
node = overallRoot = node.left;
rootFinder(node, min, max);
}
else
cutter(overallRoot, min, max);
}
感谢您的帮助。如果需要,请随时询问进一步的解释。在处理树时,我发现最容易使用递归方法,该方法获取
节点
,并返回节点
,这样我就可以调用该方法,通过对其调用该方法来“更新”我下面的节点
例如,在这种情况下,可以使用节点minBound(Node)
返回该节点的子树,该子树位于下限之上。如果当前节点
在绑定中,则递归地应用于每个子节点并返回您自己。如果当前节点
不在绑定中,则按正确的方向返回更新的子节点
。如果当前节点
为null
,则只需返回null
必须为maxBound
编写等效方法
然后只需执行minBound(maxBound(root))
即可获得树的新根
(您可以将minBound
和maxBound
组合到一个方法中,但为了便于解释,我决定将它们分开。)
编辑:因为时间太长了,我想我应该放一个代码示例来说明我的意思
public void trim(int min, int max) {
overallRoot = minBound(maxBound(overallRoot,max),min);
}
private IntTreeNode minBound(IntTreeNode node, int min) {
if (node == null) // base case of our recursion
return null;
if (node.value < min) // we're too small, but our larger children might be in
return minBound(node.right, min);
// if we make it to here then we're in bounds, so update our left child
// (our right child is bigger than us, so doesn't need to be processed)
node.left = minBound(node.left, min);
return node;
}
private IntTreeNode maxBound(IntTreeNode node, int max) {
if (node == null) // base case of our recursion
return null;
if (node.value > max) // we're too big, but our smaller children might be in
return maxBound(node.left, max);
// if we make it to here then we're in bounds, so update our right child
// (our left child is smaller than us, so doesn't need to be processed)
node.right = maxBound(node.right, max);
return node;
}
public void trim(int-min,int-max){
总体根=最小绑定(最大绑定(总体根,最大),最小);
}
私有IntTreeNode最小绑定(IntTreeNode节点,int最小){
if(node==null)//递归的基本情况
返回null;
if(node.valuemax)//我们太大了,但我们的小孩子可能在里面
返回maxBound(node.left,max);
//如果我们到了这里,那么我们就到了边界,所以更新我们的孩子
//(我们左边的孩子比我们小,所以不需要处理)
node.right=maxBound(node.right,max);
返回节点;
}
这假设节点x具有以下值:
T
成为您的树,让T.root
成为指向其根的指针。然后它可以这样工作:
overallRoot
_____[50]____________________
/ \
__________[38] _______________[90]
/ \ /
_[14] [42] [54]_____
/ \ \
[8] [20] [72]
\ / \
[26] [61] [83]
trim(52, 65);
CutBranch(x,T) {
y = T.root;
while (y.left != x && y.right != x) {
if (y < x) y = y.right;
else y = y.left;
}
if (y < x) y.right = Nil;
else y.left = Nil;
}
CutBranch(x,T){
y=T.根;
while(y.left!=x&&y.right!=x){
如果(y
当然,这假设树中不包含具有相等值的节点,但它需要O(lgn)时间。但是,它不进行任何垃圾收集
现在,您可以迭代节点,每次到达小于下限的节点时,可以调用其左子节点上的CutBranch,然后删除节点本身。如果节点大于你的上限,那么你可以把它拆分为正确的子并删除它。 < P>伟大的问题,竖起大拇指,虽然我认为如果你考虑一个不同的方法,它会变得更容易。例如,对于每个节点,首先“修剪”子节点,然后“修剪”自身
public Node trim(Node root, int min, int max){
if(root==null)
return root;
root.rightChild = trim (root.rightChild, min, max);
root.leftChild = trim (root.leftChild,min,max);
if(root.key>max || root.key<min){
if(root.rightChild!=null)
return root.rightChild;
return root.leftChild;
}
return root;
}
tree.root = trim(tree.root, min, max);
看起来像一个二叉搜索树!所有necros蝙蝠侠的圣母。我们中的一个人应该为此得到一枚徽章。
tree.root = trim(tree.root, min, max);