Vamos definir uma função split(T,v)
que recebe uma árvore T
e um valor para dividir em v
,. Suponha que cada nó da árvore armazene seu filho esquerdo e filho direito, além do valor nesse nó. Use o seguinte algoritmo:
Primeiro, verificamos se a árvore de entrada é simplesmente uma folha ou não.
Se T
não for uma folha, compare o valor do nó raiz v'
com v
.
Se, v' < v
então, chamar recursivamente a divisão na subárvore esquerda. Armazene os valores da chamada recursiva como L'
(árvore esquerda retornada), R'
(árvore direita retornada) e r
(tipo de opção indicado se o valor v
foi encontrado ou não). Construa a nova árvore certa,, newR = Node(R',v',R)
e retorne (L',r,newR)
.
Caso contrário, se v' > v
recursivamente chamar divisão na subárvore direita. Armazene os valores da chamada recursiva como L'
(árvore esquerda retornada), R'
(árvore direita retornada) e r
(tipo de opção indicado se o valor v
foi encontrado ou não). Construa a nova árvore esquerda,, newL = Node(L',v',L)
e retorne (newL,r,R')
.
Caso contrário v' = v
, volte L, SOME(v), R
.
Se T
for uma folha, devemos ter atingido a raiz da árvore sem encontrar o valor de entrada v para dividir. Retorne que você não conseguiu encontrar a folha retornando NONE
.
Por que isso é logarítmico? Bem, você apenas percorre um caminho raiz-a-folha da árvore, no máximo. Podemos reconstruir facilmente nós em tempo constante, pois estamos apenas reatribuindo referências (em uma linguagem imperativa) ou reatribuindo valores que levam um tempo constante para gerar (em uma linguagem funcional) )O(logn)O(logn)
Aqui está o código correspondente para o algoritmo. Está escrito em SML, mas eu gostaria de esclarecer o que qualquer coisa significa nos comentários.
fun split(T,v) =
case T of
Leaf => (Leaf, NONE, Leaf)
| Node(L,v,R) =>
case compare(v, v') of
LESS =>
let
val (L',r,R') = split(L,k)
in
(L',r,Node(R',r,R))
end
| GREATER =>
let
val (L',r,R') = split(R,k)
in
(Node(L',v',L),r,R')
end
| EQUAL => (L, SOME(v), R)
Veja este documento para mais detalhes. Ele fornece uma explicação mais completa do que foi dito acima.