Моя функция выглядит так (она работает неправильно, если в левом поддереве есть элементы, большие, чем 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);
}