Есть обычное AVL дерево, которое описывается следующей структурой:
typedef struct AvlNode {
struct AvlNode *parent;
struct AvlNode *left;
struct AvlNode *right;
int8_t bfactor;
double key;
} AvlNode;
typedef struct {
AvlNode *root;
size_t size;
} AvlTree;
Нужно найти все элементы, которые принадлежат интервалу. Есть следующая функция для этого:
void avl_node_print_range(AvlNode *node, double min, double max) {
if(!is_nil(node->left) && node->key > min)
avl_node_print_range(node->left, min, max);
if(node->key >= min && node->key <= max)
printf("%lf ", node->key);
if(!is_nil(node->right) && node->key < max)
avl_node_print_range(node->right, min, max);
}
void avl_print_range(AvlTree *tree, double min, double max) {
if(is_nil(tree->root))
return;
avl_node_print_range(tree->root, min, max);
fputs("\n", stdout);
}
Мне казалось, что из-за двух рекурсивных вызовов, каждый по n/2 элементов, сложность должна быть O (n). Однако в интернете на нескольких ресурсах сложность данного алгоритма была обозначена, как O(log n + M), где n - размер AVL дерева, а M - количество элементов дерева, попадающих в интервал. Доказательств ни на одном ресурсе не нашёл, а сам для оценки сложности затрудняюсь составить рекуррентное соотношение, потому что будет ли вызвана функция и сколько раз она будет вызвана зависит не от n, а от min и max. Собственно вопрос - какова на самом деле сложность данного алгоритма?