Я думаю, ваш код в комментариях был:
def sum(node=@root)
return if node.nil?
total += node.value
sum(node.left)
sum(node.right)
end
Идея почти в порядке. В nil
узлах нет суммирования; и вы суммируете значение текущего узла, левого узла и правого узла. Вот ошибки:
total += node.value
- это первый раз, когда мы видим total
. Это инициализирует это к nil
. Когда вы пытаетесь добавить node.value
к нему, вы получаете ошибку, которую вы описали. Чтобы избежать этого, либо total
должен уже существовать, либо вы можете просто присвоить node.value
.
Если функция завершается без выполнения оператора return
, она возвращает последнее вычисленное выражение; в этом случае sum(node.right)
. Не было бы лучше, если бы sum
вернул total
?
И наоборот, sum(node.left)
, вероятно, выполнит некоторое суммирование ... но его возвращаемое значение отбрасывается. Возможно, имеет смысл добавить его в total
. Говоря об итогах, может быть, мы должны сделать то же самое для sum(node.right)
.
Наконец, return if node.nil?
говорит, что вы отказываетесь суммировать узлы, которые на самом деле не являются узлами. Это здорово ... за исключением того, что return
возвращает nil
, и если вы попытаетесь получить nil
с чем-то, это не будет хорошо. Здесь есть два решения: отказаться от суммирования узла до того, как вы введете его, или сказать, что нулевой узел имеет значение 0, что не влияет на сумму.
Взяв все это вместе, вот две мои версии:
# refuse to enter a nil node:
def sum(node=@root)
total = node.value
total += sum(node.left) unless node.left.nil?
total += sum(node.right) unless node.right.nil?
total
end
# treat nil nodes as if they were zeroes:
def sum(node=@root)
return 0 if node.nil?
node.value + sum(node.left) + sum(node.right)
end