В частности, я запутался в рекурсивных вызовах внутри функции max. Что такое максимальное сравнение на каждой итерации и как можно добавить результат к 1, не вызывая ошибки TypeError?
Вы вызываете функцию дважды и передаете возвращаемые значения этих двух вызовов функции до макс. Итак, max сравнивает все, что возвращает эта функция.
Если это не ясно, давайте разберем эту строку:
left_height = get_height(root.left)
right_height = get_height(root.right)
max_height = max(left_height, right_height)
return 1 + max_height
Поскольку функция, которую мы вызываем, всегда возвращает целое число, max сравнивает два целых числа, что дает вам большее из двух целых чисел. К чему мы, очевидно, можем добавить 1 к.
Другими словами, высота дерева на 1 больше высоты того поддерева, которое выше.
Вы можете подумать, что я обманул там. Как я могу доказать, что функция всегда возвращает целое число, когда я должен был предположить, что это доказать?
Ключ в том, что рекурсия является индуктивной. Если вы не очень хорошо знаете математику, вы можете сказать следующее:
- Если базовый регистр всегда возвращает целое число,
- и рекурсия всегда вызывает меньший регистр
- и если мы всегда возвращаем целое число, пока все меньшие регистры возвращают целое число
- тогда мы всегда возвращаем целое число.
Первая часть проста: если ее нет, мы возвращаем 0.
Вторая часть происходит от определения дерева: левая ветвь дерева и правая ветвь дерева всегда являются меньшими поддеревьями дерева. (Это не будет верно для циклического графа, где root.left
может быть root
или его прародителем.)
Третья часть - это объяснение первой половины ответа.
И мы закончили.