Я полагаю, что у меня есть O (n + m) -время, O (n + m) пространственный алгоритм для решения этой проблемы, предполагая, что деревья имеют размер n и m соответственно.Этот алгоритм предполагает, что значения в деревьях уникальны (то есть каждый элемент появляется в каждом дереве не более одного раза), но они не должны быть двоичными деревьями поиска.
Алгоритм основан на динамическом программировании и работает со следующей интуицией: предположим, что у нас есть дерево T с корнем r и дочерними T1 и T2.Предположим, что другим деревом является S. Теперь предположим, что мы знаем максимальное общее поддерево T1 и S и T2 и S. Тогда максимальное поддерево T и S
- полностью содержится в T1 иr.
- полностью содержится в T2 и r.
- Используются как T1, T2, так и r.
Следовательно, мы можем вычислить максимальное общее поддерево (Я сокращу это как MCS) следующим образом.Если MCS (T1, S) или MCS (T2, S) имеют корни T1 или T2 в качестве корней, то MCS, которую мы можем получить из T и S, дается большей из MCS (T1, S) и MCS (T2).S).Если ровно один из MCS (T1, S) и MCS (T2, S) имеет корень T1 или T2 в качестве корня (предположим, wlog, что это T1), то ищите r в S. Если r имеет корень T1 какребенок, тогда мы можем расширить это дерево узлом, а MCS задается большим из этого расширенного дерева и MCS (T2, S).В противном случае, если и MCS (T1, S), и MCS (T2, S) имеют корни T1 и T2 в качестве корней, то ищите r в S. Если у него есть потомок корня T1, мы можем расширить дереводобавив в т.Если у него есть дочерний корень T2, мы можем расширить это дерево, добавив в r.В противном случае мы просто берем большее из MCS (T1, S) и MCS (T2, S).
Формальная версия алгоритма выглядит следующим образом:
- Создайте новыйХеш-таблица отображает узлы в дереве S от их значения до соответствующего узла в дереве.Затем заполните эту таблицу узлами S, выполнив стандартное обход дерева по времени O (m).
- Создайте новые узлы отображения хеш-таблицы в T от их значения до размера максимального общего поддеревадерево укоренено в этом узле и S. Обратите внимание, что это означает, что MCS-ы, хранящиеся в этой таблице, должны быть непосредственно с корнем в данном узле.Оставьте эту таблицу пустой.
- Создайте список узлов T, используя обход по порядку.Это занимает O (N) время.Обратите внимание, что это означает, что мы всегда будем обрабатывать все дочерние узлы перед самим узлом;это очень важно!
- Для каждого узла v в обходе после заказа в порядке их посещения:
- Найдите соответствующий узел в хеш-таблице для узлов S.
- Если узел не был найден, установите размер MCS с корнем в v равным 0.
- Если узел S 'был найден в S:
- Если ни один из потомковv 'соответствует дочерним элементам v, установите размер MCS с корнем в v равным 1.
- Если точно один из дочерних элементов v' совпадает с дочерним элементом v, установите размер MCS с корнем в vдо 1 плюс размер MCS поддерева с корнем у этого потомка.
- Если оба потомка v 'совпадают с потомками v, установите размер MCS с корнем в v равным 1 плюс размерMCS левого поддерева плюс размер MCS правого поддерева.
- (Обратите внимание, что шаг (4) выполняется в ожидаемом O (n)время, так как он посещает каждый узел в S ровно один раз, делает O (n) поиск хеш-таблицы, делает n вставок хеш-таблицы и делает ACпостоянное количество обработки на узел).
- Выполните итерацию по хеш-таблице и верните максимальное значение, которое она содержит.Этот шаг занимает также O (n) времени.Если хеш-таблица пуста (S имеет нулевой размер), вернуть 0.
В целом, время выполнения составляет ожидаемое время O (n + m) и пространство O (n + m) для двух хешейтаблицы.
Чтобы увидеть доказательство корректности, мы будем индуцировать по высоте дерева T. В качестве базового случая, если T имеет нулевую высоту, мы просто возвращаем ноль, потому что цикл в (4) ничего не добавляет кхеш-таблица.Если T имеет высоту один, то либо он существует в T, либо его нет.Если он существует в T, то у него вообще не может быть дочерних элементов, поэтому мы выполняем ветку 4.3.1 и говорим, что она имеет высоту один.Шаг (6) затем сообщает, что MCS имеет размер один, который является правильным.Если он не существует, то мы выполняем 4.2, помещая ноль в хеш-таблицу, поэтому шаг (6) сообщает, что MCS имеет нулевой размер, как и ожидалось.
Для индуктивного шага предположим, что алгоритм работает длявсе деревья высотой k '
Уф!Это была огромная проблема.Я надеюсь, что это решение верное!
РЕДАКТИРОВАТЬ: Как было отмечено @jonderry, это найдет самый большой общий подграф из двухдеревья, а не крупнейшее общее полное поддерево.Однако вы можете ограничить работу алгоритма только тем, что работаете только с поддеревьями.Для этого вы должны изменить внутренний код алгоритма так, чтобы он записывал поддерево размера 0, если оба поддерева отсутствуют с ненулевым размером.Подобный индуктивный аргумент покажет, что это найдет наибольшее полное поддерево.
Хотя, по общему признанию, мне больше нравится проблема "самого большого общего подграфа".: -)