我仍然不确定您存储每个子树大小的用例是什么,但是在每次插入期间很容易保持更新,而无需求助于递归。为简单起见,假设您从以下定义开始:
public static class BSTNode
{
public BSTNode leftTree = null;
public BSTNode rightTree = null;
public int subtreeSize = 1;
public int value;
public BSTNode(int valToAdd){
value = valToAdd;
}
}
public static class BST
{
public BSTNode root;
//public void insert(int valToAdd)
}
在 的实现中insert
,我们将从根开始并遍历树以找到添加新值的适当位置。我们可以随时更新每个子树的大小。一个简单的实现可能如下所示:
public void insert(int valToAdd)
{
if(root == null){
root = new BSTNode(valToAdd);
return;
}
BSTNode parent = root;
BSTNode current = root;
while(current != null){
parent = current;
++current.subtreeSize;
if(valToAdd <= current.value){
current = current.leftTree;
}
else{
current = current.rightTree;
}
}
if(valToAdd <= parent.value){
parent.leftTree = new BSTNode(valToAdd);
}
else{
parent.rightTree = new BSTNode(valToAdd);
}
}
在某些情况下,您希望从底部开始更新,例如跟踪子树高度(可能用于重新平衡)。假设BSTNode
现在的定义是:
public static class BSTNode
{
public BSTNode leftTree = null;
public BSTNode rightTree = null;
public int height = 0;
public int value;
public BSTNode(int valToAdd){
value = valToAdd;
}
}
在insert
中,使用 a Stack
(或任何可以提供 LIFO 语义的东西)来存储新插入节点的祖先。修改我们之前的简单示例:
public void insert(int valToAdd)
{
if(root == null){
root = new BSTNode(valToAdd);
return;
}
java.util.Stack<BSTNode> stack = new java.util.Stack<BSTNode>();
BSTNode parent = root;
BSTNode current = root;
while(current != null){
parent = current;
stack.push(current);
if(valToAdd <= current.value){
current = current.leftTree;
}
else{
current = current.rightTree;
}
}
if(valToAdd <= parent.value){
parent.leftTree = new BSTNode(valToAdd);
}
else{
parent.rightTree = new BSTNode(valToAdd);
}
int height = 1;
while(!stack.isEmpty()){
current = stack.pop();
current.height = Math.max(height, current.height);
++height;
}
}