各キーには、そのノードの下にあるキーの数を記録する追加のデータを保存する必要があります(ノード自体を含む)。
これを維持するには、insert(k)関数は、新しいキーkのすべての祖先をさかのぼって移動し、それらの値をインクリメントする必要があります。これにより、挿入O(log n)+ O(log n)が作成されますが、これは引き続きO(log n)であるため、複雑さには影響しません。delete(k)は、値をデクリメントすることを除いて、同じことを行う必要があります。バランシング操作でもこれを考慮に入れる必要があります。
次に、order(k)はツリーを下ってkに移動します。ノードに移動するたびに、左側にあるキーの数を合計に加算し、この合計を返す必要があります。
編集:ノードとキーの間の「ノード」のあいまいさを変更しました。これらはBツリーでは異なるためです(ノードには複数のキーを含めることができます)。ただし、アルゴリズムはほとんどのツリーデータ構造に一般化する必要があります。
これはBツリーのアルゴリズムです。
#In python-ish (untested psuedocode)
#root is the root of the tree
#Each node is expected to have an array named "keys",
# which contains the keys in the node.
#Each node is expected to have an array named "child_nodes",
# which contains the children of the node, if the node has children.
#If a node has children, this should be true: len(child_nodes) == len(keys) + 1
def inorder(q):
order_count = 0
current_node = root
while True:
#if q is after all keys in the node, then we will go to the last child node
next_child_node_i = len(current_node.keys)
#now see if q is in between any of the nodes
#for each key-index in the keys array (ie. if the node contains 3 keys,
# keyi will be in range [0-2] .)
for keyi in range(len(current_node.keys)):
#retrieve the value of the key, so we can do comparison
current_key = current_node.keys[keyi]
if current_key < q:
#We are trying to find which child node to go down to next,
# for now we will choose the child directly to the left of this key,
#But we continue to look through the rest of the keys, to find which
# two keys q lies in between.
#before we continue, we should count this key in the order too:
#if this is not a leaf node,
if len(current_node.children) != 0:
#retrieve the the recorded child count of the sub-tree
order_count += current_node.children[keyi].recorded_descendant_key_count
#add one for the key in this node that we are skipping.
order_count += 1
continue
if q < current_key:
#We found a key in the current node that is greater than q.
#Thus we continue to the next level between this and the previous key.
next_child_node_i = keyi
break
#we finally found q,
if q == current_key:
#now we just return the count
return order_count
#once we are here, we know which keys q lies between
# (or if it belongs at the beginning or end), and thus which child to travel down to.
#If this is a leaf node (it has no children),
# then q was not found.
if len(current_node.child_nodes) == 0:
#Possible behaviors: throw exception, or just return the place in the order
# where q *would* go, like so:
return order
#Travel down a level
current_node = current_node.child_nodes[next_child_node_i]