Сопоставление с образцом
Подведем итоги. Рассмотренный способ хранения деревьев
позволяет (для фиксированного слова )
- создать дерево из одного корня [
];
- найти отца любой вершины (кроме корня) [
];
- узнать пометку любой вершины (кроме корня), то есть
пометку ведущего к ней ребра [
];
- пройти из любой позиции
вдоль любого слова
, если заранее известно, что мы не выйдем из дерева; результатом является позиция
в дереве, для которой
[ O (число ребер на пути)];
- добавить слово
, начав с позиции
; если при этом слово
является подсловом
, а в дереве нет позиции
, для которой
, то дерево меняется и такая позиция
создается (она будет листом) [ O (число букв в w, не вошедших в l(q) ];
- наконец, для любого слова
можно выяснить, найдется ли в дереве позиция
, для которой
[
].
В квадратных скобках указано число действий при выполнении соответствующих операций.
Еще мы будем хранить в вершинах дерева " суффиксные ссылки " (в каждой вершине будет не более одной ссылки на другую вершину), но сначала надо объяснить, что это такое.
Начнем с полного (не сжатого) суффиксного дерева для
слова . Каждой его вершине (кроме корня) отвечает
некоторое непустое подслово слова
. Если мы отрежем
у этого подслова последнюю букву, то в дереве спустимся на
один шаг к корню. Но что будет, если мы отрежем первую
букву? Снова получится подслово, но оно уже будет совсем
в другом месте дерева.
Вот как выглядят эти переходы в нашем примере (отрезание первой буквы соответствует пунктирной стрелке):
Эти стрелки мы будем называть суффиксными ссылками, поскольку они соответствуют переходу от слова к его суффиксу на единицу меньшей длины. Они определены для всех вершин, кроме корня.
Формально можно сказать так. Пусть означает
слово
без первой буквы (
определено для любого непустого
слова
). Тогда суффиксная ссылка ведет из вершины
в вершину
, если
(напомним, что
- слово, соответствующее вершине
).
10.8.5. Как связаны суффиксные ссылки двух соседних вершин (отца и сына)?
Ответ. Они указывают на соседние вершины, и буква на соединяющем их ребре та же самая.
10.8.6. Доказать, что при переходе к сжатому суффиксному дереву ссылки по-прежнему идут из вершины в вершину (а не внутрь ребер).
Решение. В самом деле, по нашему предположению последняя
буква слова больше в нем не встречается, поэтому из листа
ссылка ведет в лист. А если вершина (отличная от корня)
является точкой ветвления, то соответствующее ей слово
встречается с различными буквами после него. Другими
словами, для некоторых букв
и
слова
и
являются подсловами слова
. Отрезав от них первую букву,
получим слова
и
, которые также являются
подсловами слова
, поэтому и
является точкой
ветвления.
Вот что получится для нашего примера:
Теперь мы уже готовы к изложению алгоритма МакКрейта. Сжатое суффиксное дерево строим постепенно, добавляя к нему
суффиксы по мере уменьшения их длины. Обозначим через
суффикс, начинающийся с
-ой буквы слова
. (Таким
образом,
, а
состоит из одной буквы.) После
шагов построения наше дерево будет хранить
.
10.8.7.
Показать, что суффиксные ссылки в таком дереве определены
корректно (ведут в другую вершину того же дерева) для всех
вершин, кроме, возможно, последнего добавленного листа
(соответствующего слову ) и его отца.
Решение.
В самом деле, суффиксная ссылка из листа ведет
в лист
, и потому ей есть куда вести. Рассмотрим
теперь внутреннюю вершину
, не являющуюся отцом
последнего листа. Пусть в ней разветвляются два пути
в листья
и
. Без ограничения общности можно
считать, что
(если один из путей ведет в
,
то его можно заменить другим, ведь вершина
по
предположению не последняя развилка на этом пути). Отрезав
от этих путей первый символ, получим пути
в листья
и
; эти пути присутствуют
в дереве (поскольку
и
не
превосходят
),
а точка их развилки будет концом суффиксной ссылки вершины
.
Суффиксные ссылки для листьев нам не понадобятся,
и вычислять мы их не будем, а для всех остальных вершин
дерева мы их будем вычислять и хранить. Более точно, после шагов алгоритма