Самый простой ответ: O(n)
. Вы посещаете каждый узел один раз и выполняете один (а) объем работы. Расчет будет выглядеть как
O(a*n)
и поскольку мы игнорируем постоянные факторы, простой ответ будет
O(n)
Но . Можно также утверждать, что вы делаете немного больше: вы возвращаете null
каждый раз, когда посещаете место, где нет листьев. Это опять-таки один (б) объем работы, который нужно сделать.
Давайте на минутку назовем эти невидимые листья . Следуя этой идее, каждое значение в дереве - это узел , который имеет один или два невидимых листа .
Итак, теперь у нас есть следующее (для каждого узла):
a | if a node has two child nodes
a + b | if a node has one child node
a + 2b | if a node has no child node.
для двоичного дерева наихудшего случая (полностью несбалансированного) у нас есть (n-1) узлов с одним дочерним узлом и одним узлом без дочерних узлов:
"1"
\
"2"
\
"3"
\
"4"
Итак, расчет
(n-1)*(a+b) + b
<=> an + bn - a - b + b
<=> n(a+b) + b
=> O(an + bn) // we ignore `+ b` because we always look at really big n's
К счастью, даже в худшем случае сложность все еще линейна. Только константа выше, чем в простом ответе. В большинстве случаев - обычно, когда Big-O необходим для сравнения алгоритмов - мы даже игнорируем фактор, и мы рады сказать, что временная сложность алгоритмов линейна (O (n)).