Agora que temos uma ideia geral do que é uma árvore binária de busca, vamos conversar sobre ela de maneira um pouco mais detalhada. Árvores de pesquisa binária fornecem tempo logarítmico para operações comuns de pesquisa, inserção e exclusão em média e tempo linear no pior dos casos. Por quê? Cada uma dessas operações básicas exige que encontremos um item na árvore (ou, no caso da inserção, encontrar onde ele deve ir). Por causa da estrutura das árvores, em cada nó pai, estamos ramificando à esquerda ou à direita e excluindo efetivamente metade do tamanho da árvore restante. Isto torna a busca proporcional ao logaritmo do número de nós na árvore, o que cria tempo logarítmico para estas operações em média. Certo, mas e no pior dos casos? Bem, considere a construção de uma árvore a partir dos seguintes valores, adicionando-os da esquerda para a direita: `10`, `12`, `17`, `25`. Seguindo nossas regras para uma árvore binária de busca, vamos adicionar `12` à direita de `10`, `17` à direita deste e `25` à direita deste. Agora, nossa árvore se parece com uma lista encadeada. Atravessá-la para encontrar `25` nos obrigaria a atravessar todos os itens de forma linear. Assim, o tempo seria linear no pior dos casos. O problema aqui é que a árvore é desbalanceada. Vamos examinar um pouco melhor o que isso significa nos próximos desafios.
Neste desafio, criaremos um utilitário para a nossa árvore. Escreva um método `isPresent`, que recebe um valor inteiro como entrada e retorna um valor booleano para a presença ou ausência desse valor na árvore binária de busca.