Мы можем решить эту проблему с помощью базового c случая индукции. По сути, давайте начнем с базового случая, а затем, предполагая, что любой вариант n
работает, мы должны проверить, работает ли случай n+1
. В случае вычисления высот узлов в двоичном дереве базовый случай - это когда узел root является листовым узлом, а для случая n+1
узлы левой / правой стороны - это варианты n
. Вы можете думать об этом так, как n - это высота текущего узла, а n=0
- это базовый случай листового узла.
Когда узел root является листом, левый и правый узлы являются nullptr
метод по существу превращается в
void computeHeight(Node *n) {
int leftHeight = -1;
int rightHeight = -1;
n->height = std::max(leftHeight, rightHeight) + 1;
}
, и в этом случае n->height
становится 0
, что правильно для листового узла. Теперь, когда узел не является листовым, операторы
computeHeight(n->left);
computeHeight(n->right);
уже вызываются перед вычислением. По сути, это делает так, что мы предполагаем, что и левый, и правый узлы уже позаботились, и их высота правильная. Затем мы можем использовать высоту левого и правого узлов для вычисления высоты root узла, которая вычисляется через
int leftHeight = -1;
int rightHeight = -1;
if (n->left != nullptr) {
leftHeight = n->left->height;
}
if (n->right != nullptr) {
rightHeight = n->right->height;
}
n->height = std::max(leftHeight, rightHeight) + 1;
Хитрость здесь в том, что мы уже вызвали computeHeight()
слева и правые боковые узлы, так что, когда мы делаем вычисления на текущем узле, мы можем с уверенностью предположить, что дочерние узлы полностью позаботились. Кроме того, дочерние узлы вычисляются перед узлом root, поэтому программа сначала просочится вниз к листьям, а затем вернется вверх и вычислит нелистовые узлы.