Самая короткая ветвь в двоичном дереве?

Двоичное дерево может быть закодировано с использованием двух функций l и r, так что для node n, l(n) дает левый дочерний элемент n, r(n) дает правый дочерний элемент n.

Ветвь дерева - это путь от корня к листу, длина ветви до конкретного листа - это количество дуг на пути от корня к этому листу.

Пусть MinBranch(l,r,x) будет простым рекурсивным алгоритмом для взятия двоичного дерева, закодированного функциями l и r, вместе с корневым узлом x для двоичного дерева, и возвращает длину кратчайшей ветви двоичного дерева.

Приведите псевдокод этого алгоритма.

Хорошо, в основном это то, что я придумал до сих пор:

MinBranch(l, r, x)
{
    if x is None return 0

    left_one = MinBranch(l, r, l(x))

    right_one = MinBranch(l, r, r(x))

    return {min (left_one),(right_one)}
}

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


person Community    schedule 28.08.2009    source источник
comment
Я бы сказал, что у вас неплохая версия, нечего добавить к ней.   -  person Paulius    schedule 28.08.2009
comment
Кстати, вы также можете отредактировать свой вопрос со вчерашнего дня (stackoverflow.com/questions/1339043…) ... таким образом, вы не Не нужно все перефразировать.   -  person Roland Ewald    schedule 28.08.2009
comment
-1 за плохой заголовок, удаление вашего вопроса и просьбу к людям решить вашу проблему вместо того, чтобы просить намек на что-то конкретное, что вас ставит в тупик   -  person mpen    schedule 28.08.2009
comment
Почему вы стерли свой вопрос?   -  person Ed S.    schedule 06.09.2009


Ответы (5)


Сомневаюсь, что кто-то решит за тебя домашнее задание. Подсказка: возвращаемое значение обязательно должно расти по мере того, как дерево становится больше, верно? Однако я не вижу в вашей функции никаких числовых литералов, кроме 0, а также операторов сложения. Как вы когда-нибудь вернете большие числа?

Другой взгляд на ту же проблему: в любое время вы пишете рекурсивную функцию, это помогает перечислить, «при каких условиях я должен перестать называть себя? Что я возвращаю в каждом случае?»

person Richard Berg    schedule 28.08.2009

Вы находитесь на правильном пути, но вы не совсем там; ваш рекурсивный алгоритм всегда будет возвращать 0. (хотя логика почти верна ...)

обратите внимание, что длина ответвлений на единицу меньше длины ответвления; поэтому left_one и right_one должны быть 1 + MinBranch....

Пошаговое выполнение алгоритма с использованием нескольких образцов деревьев поможет выявить отдельные ошибки, подобные этой ...

person Stobor    schedule 28.08.2009

Похоже, он у вас почти есть, но рассмотрим этот пример:

      4

   3     5

Когда вы проследите MinBranch, вы увидите это в своем MinBranch(l,r,4) вызове:

left_one = MinBranch(l, r, l(x))
         = MinBranch(l, r, l(4))
         = MinBranch(l, r, 3)
         = 0

В конце концов, это имеет смысл, 3 - это листовой узел, поэтому, конечно, расстояние до ближайшего листового узла равно 0. То же самое происходит и с right_one.

Но потом вы попадаете сюда:

return {min (left_one),(right_one)}
     = {min (0), (0) }
     = 0

но это явно неверно, потому что этот узел (4) не является листовым. Ваш код забыл подсчитать текущий узел (упс!). Я уверен, ты сможешь это исправить.


На самом деле, ваш способ, которым вы это делаете, не самый быстрый, но я не уверен, подходит ли это для этого упражнения. Рассмотрим это дерево:

         4
       3   5
     2
   1

Ваш алгоритм будет рекурсивно подсчитывать левую ветвь, даже если он гипотетически может выйти из строя, если вы сначала посчитали правую ветвь и заметили, что у 3 есть левая, поэтому она явно длиннее 5 (что является листом). Но, конечно, не всегда удается сначала подсчитать правильную ветку!

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

person derobert    schedule 28.08.2009
comment
вот дерьмо: | эээ, так что если я сделаю 1 + minbranch (l, r, l (x)), это сработает, верно? - person ; 28.08.2009
comment
@rachel: Думаю, да, но тебе стоит попробовать это на некоторых деревьях, чтобы проверить. В конце концов, вы потеряете очки, если этого не произойдет, а не я :-D - person derobert; 28.08.2009
comment
спасибо dero за редактирование и помощь мне несколько раз - меня не интересуют время и память, так как это чисто теоретический вопрос :) - person ; 28.08.2009

То, что вы создали, можно рассматривать как поиск в глубину. Однако, учитывая то, что вам нужно (самая короткая ветвь), это может быть не самый эффективный подход. Подумайте о том, как ваш алгоритм будет работать с деревом, которое было очень тяжелым с левой стороны (корневого узла), но имело только один узел с правой стороны.

Подсказка: рассмотрите подход поиска в ширину.

person MadCoder    schedule 28.08.2009
comment
спасибо, постараюсь придумать лучшее решение, используя bfs cheers :) - person ; 28.08.2009
comment
Если вам нужна эффективность, то BFS не намного лучше - вы просто меняете затраты времени на стоимость места. IDDFS сочетает в себе лучшие атрибуты обоих с небольшими накладными расходами. - person Richard Berg; 28.08.2009

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

person Charles Ma    schedule 28.08.2009
comment
+1 вот что я собирался предложить. Поиск в ширину с использованием очереди (или стека) - это правильный подход для поиска самого мелкого листового узла (что является другим способом выразить эту проблему). - person cletus; 28.08.2009
comment
Хотя ваш комментарий полезен для решения проблемы в целом, я должен проголосовать против, потому что он не очень полезен для проблемы домашнего задания. В частности, потому что студент должен использовать и определять MinBranch для определенных аргументов, и я не вижу, как разумно реализовать алгоритм BFS с такими ограничениями. Если я ошибаюсь, считайте, что знак моего голоса перевернут. :) - person agorenst; 28.08.2009