Моя функция выглядит так (она работает неправильно, если в левом поддереве есть элементы, большие, чем key; Здесь tree->left - левое поддерево, tree->right - правое; Value - пользовательский тип данных; comparator - функция сравнения):
Value getUpperBound(Tree* tree, Value key)
{
if (!tree)
return wrapNone();
return tree->comparator(tree->key, key) > 0 ? tree->key : getUpperBound(tree->right, key);
}