Обход по порядку || Пространство стека вызовов следует учитывать (или) Нет?

Этот вопрос был у меня в голове в течение многих дней, и я хотел, чтобы кто-нибудь прояснил его. Задача: найти количество узлов в бинарном дереве.

Подход 1:- (Итеративный) Выполните обход в порядке, используя стек. всякий раз, когда вы извлекаете элементы из стека, подсчитывайте их количество узлов в двоичном дереве.

Временная сложность - O (n)

Космическая сложность - O(n)

Подход 2:- (Рекурсивный)

Временная сложность - O (n)

Космическая сложность - O(1) или O(n)????

Мы можем сделать обход рекурсивно, но в интервью, какой подход был бы оптимальным, выражая интервьюеру..... Итеративный или рекурсивный?? а также следует ли мне учитывать пространство стека рекурсивных вызовов, которое сводит пространственную сложность к O (n), или мне следует придерживаться пространственной сложности O (1)?


person Sai Avinash Duddupudi    schedule 12.11.2019    source источник
comment
Да, вы должны учитывать стек вызовов при рассмотрении сложности пространства. Обратите внимание, что пространственная сложность для обоих алгоритмов равна O(h), где h — высота дерева; не O(n), где n — количество узлов.   -  person kaya3    schedule 12.11.2019
comment
@ kaya3, тогда в этом случае для определения количества узлов подход стека тоже подходит, верно ???   -  person Sai Avinash Duddupudi    schedule 13.11.2019


Ответы (1)


На ваш вопрос - "какой подход будет оптимальным для интервьюера" - на самом деле не может ответить никто, кроме самого интервьюера. Однако различия между возможными подходами к этой проблеме заслуживают обсуждения.


Для начала отметим, что итеративный, и рекурсивный подходы используют стек; итеративный подход имеет явный стек, но рекурсивная функция работает с использованием стека вызовов, который не управляется программистом. Следовательно, вспомогательное пространство, используемое при любом подходе, будет асимптотически одним и тем же, но с более низкой константой для итеративного подхода, поскольку он помещает в стек только узлы, а рекурсивный подход помещает все кадры вызовов, включая все локальные переменные.

Обратите внимание, что вспомогательное пространство равно O(h), где h — высота дерева, а не O(n), где n — количество узлов. Это важно, поскольку наихудший случай будет зависеть от того, является ли дерево сбалансированным. Для несбалансированного дерева высота h равна O(n) в худшем случае, тогда как для сбалансированного дерева h равна O(log н). В вопросе не указывается, что дерево сбалансировано, поэтому существует риск того, что рекурсивный подход переполнит stack, когда высота дерева слишком велика. Напротив, итеративный подход сохраняет явный стек в основной памяти.


Это все обсуждение эффективности, но в программировании есть нечто большее, чем алгоритмическая эффективность. Например, если дерево никогда не будет очень большим, вы можете предпочесть рекурсивный подход, так как его намного проще писать; требуется всего несколько строк очень чистого кода. Императивный подход требует создания стека, а также извлечения и извлечения из него в цикле, поэтому код, вероятно, будет длиннее и труднее для понимания. Не стоит недооценивать ценность чистого, легкого для понимания кода.


Другое дело, что вы перешли сразу к обходу по порядку как к решению проблемы, но если задача состоит в том, чтобы подсчитать количество узлов в двоичном дереве, то вы можете проходить его в любом порядке. Обход в предварительном порядке немного проще реализовать итеративно, чем обход в порядке, и он столь же эффективен.

В качестве альтернативы, если сама структура данных может быть изменена, то легко дать каждому узлу свойство, содержащее кардинальность его поддерева. Операции вставки, удаления и повторной балансировки должны быть изменены, чтобы сохранить это свойство, но дополнительная работа составляет O (1), и это позволяет вычислить размер дерева за O (1), просто читая кардинальность корневого узла. свойство. Добавление этого свойства имеет и другие преимущества, такие как поддержка операции «найти k-й узел» за время O(h) вместо O(h) > + k).

person kaya3    schedule 13.11.2019
comment
вау... Это какое-то ясное объяснение... Большое спасибо, что нашли время и объяснили это ясно. - person Sai Avinash Duddupudi; 14.11.2019