各サブツリーのサイズを保存するためのユースケースが何であるかはまだわかりませんが、再帰に頼らずに各挿入中に更新を維持するのは簡単です。簡単にするために、次の定義から始めるとします。
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
、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;
}
}