<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
		<id>http://neerc.ifmo.ru/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=212.193.77.54&amp;*</id>
		<title>Викиконспекты - Вклад участника [ru]</title>
		<link rel="self" type="application/atom+xml" href="http://neerc.ifmo.ru/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=212.193.77.54&amp;*"/>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A1%D0%BB%D1%83%D0%B6%D0%B5%D0%B1%D0%BD%D0%B0%D1%8F:%D0%92%D0%BA%D0%BB%D0%B0%D0%B4/212.193.77.54"/>
		<updated>2026-04-11T06:03:21Z</updated>
		<subtitle>Вклад участника</subtitle>
		<generator>MediaWiki 1.30.0</generator>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A3%D0%BA%D0%BA%D0%BE%D0%BD%D0%B5%D0%BD%D0%B0&amp;diff=27692</id>
		<title>Алгоритм Укконена</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A3%D0%BA%D0%BA%D0%BE%D0%BD%D0%B5%D0%BD%D0%B0&amp;diff=27692"/>
				<updated>2012-12-15T16:55:20Z</updated>
		
		<summary type="html">&lt;p&gt;212.193.77.54: /* Суффиксные ссылки */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{В разработке}}&lt;br /&gt;
'''Алгоритм Укконена''' — алгоритм построения [[Сжатое суффиксное дерево|суффиксного дерева]] для заданной строки &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt; за линейное время.&lt;br /&gt;
&lt;br /&gt;
== Первая версия алгоритма ==&lt;br /&gt;
Рассмотрим сначала метод, который строит дерево за время &amp;lt;tex&amp;gt;O(n^3)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; — длина исходной строки &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt;. В дальнейшем данный алгоритм будет оптимизирован таким образом, что будет достигнута линейная скорость работы.&lt;br /&gt;
&lt;br /&gt;
=== Описание ===&lt;br /&gt;
Алгоритм делится на &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; фаз. В фазе с номером &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; в дерево добавляются все суффиксы подстроки &amp;lt;tex&amp;gt;s_{1..i}&amp;lt;/tex&amp;gt;. При добавлении суффикса &amp;lt;tex&amp;gt;s_{j..i}&amp;lt;/tex&amp;gt; алгоритм сначала находит конец пути из корня, помеченного подстрокой &amp;lt;tex&amp;gt;s_{j..i-1}&amp;lt;/tex&amp;gt;, затем добавляет к найденной вершине новое ребро с листом &amp;lt;tex&amp;gt;s_i&amp;lt;/tex&amp;gt;, если этот символ не был добавлен ранее.&lt;br /&gt;
&lt;br /&gt;
=== Псевдокод ===&lt;br /&gt;
Приведенный алгоритм можно записать с помощью псевдокода:&lt;br /&gt;
 '''for''' &amp;lt;tex&amp;gt; i \leftarrow 1 &amp;lt;/tex&amp;gt; '''to''' &amp;lt;tex&amp;gt; n &amp;lt;/tex&amp;gt; '''do'''&lt;br /&gt;
   '''for''' &amp;lt;tex&amp;gt; j \leftarrow 1 &amp;lt;/tex&amp;gt; '''to''' &amp;lt;tex&amp;gt; i &amp;lt;/tex&amp;gt; '''do'''&lt;br /&gt;
     insert(&amp;lt;tex&amp;gt;s_{j..i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
Поскольку операция insert может занимать линейное время, очевидно, что время работы данного алгоритма составляет &amp;lt;tex&amp;gt;O(n^3)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Возможные исходы операции insert ==&lt;br /&gt;
Ниже приведены три возможных случая, которые могут возникнуть при добавлении подстроки &amp;lt;tex&amp;gt;s_{j..i}&amp;lt;/tex&amp;gt; в дерево.&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;5&amp;quot; cellspacing=&amp;quot;0&amp;quot; style=&amp;quot;text-align:center&amp;quot; width=70%&lt;br /&gt;
!style=&amp;quot;background:#f2f2f2&amp;quot;|Случай&lt;br /&gt;
!style=&amp;quot;background:#f2f2f2&amp;quot;|Правило&lt;br /&gt;
!style=&amp;quot;background:#f2f2f2&amp;quot;|Пример&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#ffffff&amp;quot;|''1. Продление листа''&lt;br /&gt;
|style=&amp;quot;background:#ffffff&amp;quot;|Пусть подстрока &amp;lt;tex&amp;gt;s_{j..i-1}&amp;lt;/tex&amp;gt; кончается в листе. Добавим элемент &amp;lt;tex&amp;gt;s_i&amp;lt;/tex&amp;gt; в конец последнего ребра.&lt;br /&gt;
|style=&amp;quot;background:#ffffff&amp;quot;|[[Файл:Case2.png]]&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#ffffff&amp;quot;|''2. Создание листа''&lt;br /&gt;
|style=&amp;quot;background:#ffffff&amp;quot;|Пусть подстрока &amp;lt;tex&amp;gt;s_{j..i-1}&amp;lt;/tex&amp;gt; кончается в вершине, не являющейся листом, из которой нет пути по символу &amp;lt;tex&amp;gt;s_i&amp;lt;/tex&amp;gt;. Создадим новую дугу с началом в элементе &amp;lt;tex&amp;gt;s_{i-1}&amp;lt;/tex&amp;gt; и листом &amp;lt;tex&amp;gt;s_i&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|style=&amp;quot;background:#ffffff&amp;quot;|[[Файл:Case1.png]]&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background:#ffffff&amp;quot;|''3. Ничего не делать''&lt;br /&gt;
|style=&amp;quot;background:#ffffff&amp;quot;|Пусть подстрока &amp;lt;tex&amp;gt;s_{j..i-1}&amp;lt;/tex&amp;gt; кончается в вершине, из которой есть путь по &amp;lt;tex&amp;gt;s_i&amp;lt;/tex&amp;gt;. Тогда ничего делать не надо.&lt;br /&gt;
|style=&amp;quot;background:#ffffff&amp;quot;|[[Файл:Case3.png]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Оптимизация алгоритма Укконена==&lt;br /&gt;
&lt;br /&gt;
Рассмотрим две леммы, позволяющие ускорить алгоритм Укконена до &amp;lt;tex&amp;gt;O(n^2)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
===Лемма 1. Стал листом {{---}} листом и останешься ===&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
Если в какой-то момент работы алгоритма Укконена будет создан лист с меткой &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; (для суффикса, начинающегося в позиции &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; строки &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;), он останется листом во всех последовательных деревьях, созданных алгоритмом. &lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
|proof=&lt;br /&gt;
Это верно потому, что у алгоритма нет механизма продолжения листового ребра дальше текущего листа. Если есть лист с суффиксом &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;, правило продолжения 1 будет применяться для продолжения &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; на всех последующих фазах.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===Лемма 2. Правило 3 заканчивает дело ===&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
В любой фазе, если правило продолжения 3 применяется в продолжении &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;, оно будет реализовываться во всех дальнейших продолжениях(от &amp;lt;tex&amp;gt;j + 1&amp;lt;/tex&amp;gt; по &amp;lt;tex&amp;gt;i + 1&amp;lt;/tex&amp;gt;) до конца фазы. &lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
|proof=&lt;br /&gt;
При использовании правила продолжения 3 путь, помеченный &amp;lt;tex&amp;gt;S[j..i]&amp;lt;/tex&amp;gt; в текущем дереве, должен продолжаться символом &amp;lt;tex&amp;gt;i+1&amp;lt;/tex&amp;gt;⁠, и точно так же продолжается путь, помеченный &amp;lt;tex&amp;gt;S[j + 1..i]&amp;lt;/tex&amp;gt;⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠, поэтому правило 3 применяется в продолжениях &amp;lt;tex&amp;gt;j + 1, j + 2, ..., i + 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
Когда используется правило 3, никакой работы делать не нужно, так как требуемый суффикс уже в дереве есть. Поэтому можно заканчивать каждую фазу &amp;lt;tex&amp;gt;i + 1&amp;lt;/tex&amp;gt; после первого же использования правила прохождения 3. Если это случится в продолжении j, то уже не требуется явно находить концы строк &amp;lt;tex&amp;gt;S[k..i]&amp;lt;/tex&amp;gt; с &amp;lt;tex&amp;gt;k &amp;gt; j&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Алгоритм Укконена за квадратичное время==&lt;br /&gt;
&lt;br /&gt;
Рассмотрим правила продолжения суффиксов.&lt;br /&gt;
&lt;br /&gt;
При использовании правила 1 по лемме 1 в последующих фазах будет выполняться правило 1. Поэтому скажем, что мы создаём лист не только для рассмотренной части строки, а для всей всей строки до конца. &amp;lt;br /&amp;gt;&lt;br /&gt;
При использовании правила 2 появится новый лист, который далее будет продлеваться по правилу 1. &amp;lt;br /&amp;gt;&lt;br /&gt;
При использовании правила 3 по лемме 2 никакой работы делать не нужно, поскольку суффикс в дереве уже есть. Следовательно, можно остановиться и не добавлять следующие суффиксы.&lt;br /&gt;
&lt;br /&gt;
Таким образом, операция insert позволяет суффиксы не только для подстрок &amp;lt;tex&amp;gt;S[j..i]&amp;lt;/tex&amp;gt;, но и сразу для всего суффикса &amp;lt;tex&amp;gt;S[j..n]&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Псевдокод ===&lt;br /&gt;
Приведенный алгоритм можно записать с помощью псевдокода:&lt;br /&gt;
 '''for''' &amp;lt;tex&amp;gt; i \leftarrow 1 &amp;lt;/tex&amp;gt; '''to''' &amp;lt;tex&amp;gt; n &amp;lt;/tex&amp;gt; '''do'''&lt;br /&gt;
     insert(&amp;lt;tex&amp;gt;s_{i..n}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
Поскольку операция insert по-прежнему занимает линейное время, очевидно, что время работы данного алгоритма составляет &amp;lt;tex&amp;gt;O(n^2)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Суффиксные ссылки==&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition= Пусть &amp;lt;tex&amp;gt;x\alpha&amp;lt;/tex&amp;gt; обозначает произвольную строку, где &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; {{---}} ее первый символ, а &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; {{---}} оставшаяся подстрока(возможно пустая). Если для внутренней вершины &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; с путевой меткой &amp;lt;tex&amp;gt;x\alpha&amp;lt;/tex&amp;gt; существует другая вершина &amp;lt;tex&amp;gt;s(v)&amp;lt;/tex&amp;gt;  с путевой меткой &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt;, то ссылка из &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;s(v)&amp;lt;/tex&amp;gt; называется '''суффиксной ссылкой'''.}}&lt;br /&gt;
&lt;br /&gt;
===Лемма 3. Существование суффиксных ссылок ===&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
Для любой внутренней вершины &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; суффиксного дерева существует суффиксная ссылка, ведущая в некоторую внутреннюю вершину &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|proof=&lt;br /&gt;
Рассмотрим внутренную вершину &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; с путевой меткой &amp;lt;tex&amp;gt;t_i ... t_j&amp;lt;/tex&amp;gt;. Так как эта вершина внутренняя, ее путевая метка ветвится справа в исходной строке. Тогда очевидно подстрока &amp;lt;tex&amp;gt;t_{i+1} ... t_j&amp;lt;/tex&amp;gt; тоже ветвится справа в исходной строке, и ей соответствует некоторая внутренняя вершина &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt;. По определению суффиксная ссылка вершины &amp;lt;tex&amp;gt;v &amp;lt;/tex&amp;gt; ведет в &amp;lt;tex&amp;gt; u&amp;lt;/tex&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Построение суффиксных ссылок ===&lt;br /&gt;
&lt;br /&gt;
Заметим что в процессе построения суффиксного дерева уже построенные суффиксные ссылки никак не изменяются. Опишем процесс построения суффиксной ссылки для новой созданной внутренней вершины. Пусть в результате очередного продления была создана новая внутренняя вершина &amp;lt;tex&amp;gt;v &amp;lt;/tex&amp;gt; с путевой меткой &amp;lt;tex&amp;gt;t_i ... t_j&amp;lt;/tex&amp;gt;. Перейдем к следущему шагу текущей фазы, на котором в дерево будет добавлен суффикс &amp;lt;tex&amp;gt;t_{i + 1} ... t_j&amp;lt;/tex&amp;gt; соответствующий вершине &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; (возможно до продления суффикс оканчивался на ребре, но в этом случае по рассуждениям аналогичным Лемме 1 будет создана новая внутрення вершина). По определению суффиксная ссылка из вершины &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; ведет в &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Использование суффиксных ссылок ===&lt;br /&gt;
&lt;br /&gt;
Опишем как искать концы суффиксов в дереве, которые нужно продлить. Пусть мы только что продлили суффикс &amp;lt;tex&amp;gt;t_i ... t_j&amp;lt;/tex&amp;gt;. Найдем с помощью построенных ссылок конец суффикса &amp;lt;tex&amp;gt;t_{i + 1} ... t_j&amp;lt;/tex&amp;gt;. Пройдем вверх по дереву от конца суффикса &amp;lt;tex&amp;gt;t_i ... t_j&amp;lt;/tex&amp;gt; до ближайшей внутренней вершины &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt;. Ей соответствует некоторая подстрока &amp;lt;tex&amp;gt;t_i ... t_k &amp;lt;/tex&amp;gt;. У вершины &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; есть суффиксная ссылка, так как ссылка для новой внутренней вершины строится внутри фазы ее создания. Пусть суффиксная ссылка ведет в вершину &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt;, которой соответствует подстрока &amp;lt;tex&amp;gt;t_{i + 1} ... t_k&amp;lt;/tex&amp;gt;. Теперь пройдем от вершины &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; пройдем вниз по дереву, читая текст &amp;lt;tex&amp;gt;t_{k + 1} ... t_j&amp;lt;/tex&amp;gt;, и придем к концу суффикса &amp;lt;tex&amp;gt;t_{i + 1} ... t_j&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Оценка числа переходов ====&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition= '''Глубиной вершины''' &amp;lt;tex&amp;gt;d(v)&amp;lt;/tex&amp;gt; назовем число ребер на пути от корня до вершины &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
===== Лемма 4. =====&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
При переходе по суффиксной ссылке глубина уменьшается не более чем на 1.&lt;br /&gt;
|proof=&lt;br /&gt;
Пусть мы переходим из вершины &amp;lt;tex&amp;gt; v &amp;lt;/tex&amp;gt; с путевой меткой &amp;lt;tex&amp;gt;t_i ... t_j&amp;lt;/tex&amp;gt; по суффиксной ссылке в вершину &amp;lt;tex&amp;gt; u &amp;lt;/tex&amp;gt; с путевой меткой &amp;lt;tex&amp;gt;t_{i + 1} ... t_j&amp;lt;/tex&amp;gt; Определим множество &amp;lt;tex&amp;gt; A &amp;lt;/tex&amp;gt; как множество вершин на пути от корня до &amp;lt;tex&amp;gt; u &amp;lt;/tex&amp;gt;, исключая корень. Множество &amp;lt;tex&amp;gt; B &amp;lt;/tex&amp;gt; определим как множество вершин на пути от корня до &amp;lt;tex&amp;gt; v &amp;lt;/tex&amp;gt;, исключая корень. Если длина первого ребра на пути от корня до &amp;lt;tex&amp;gt; v &amp;lt;/tex&amp;gt; равна единице, то выкинем из множества &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; вершину, в которую ведет это ребро. Итого по построению получаем: &amp;lt;tex&amp;gt;|A| = d(u)&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;|B| \ge d(v) - 1&amp;lt;/tex&amp;gt;. Теперь заметим, что суффиксная ссылка из любой вершины множества &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; ведет в некоторую вершину множества &amp;lt;tex&amp;gt; A&amp;lt;/tex&amp;gt;, и очевидно суффиксные ссылки из разных вершин ведут в разные вершины, поэтому &amp;lt;tex&amp;gt;|A| \ge |B|&amp;lt;/tex&amp;gt;, а значит &amp;lt;tex&amp;gt;d(u) \ge d(v) - 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===== Лемма 5. =====&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
Число переходов по ребрам внутри фазы номер &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; не превышает &amp;lt;tex&amp;gt;4i&amp;lt;/tex&amp;gt;&lt;br /&gt;
|proof=&lt;br /&gt;
Оценим количество переходов по ребрам при поиске конца суффикса. Переход до ближайшей внутренней вершины уменьшает высоту на 1. Переход по суффиксной ссылке уменьшает высоту не более чем на 1 (по Лемме). Значит в течение одной фазы вверх мы переходим не более &amp;lt;tex&amp;gt; 2i &amp;lt;/tex&amp;gt; раз. Но внутри одной фазы начальная глубина не меньше конечной (так как длины суффиксов убывают до 1), поэтому вниз мы могли пройти не более &amp;lt;tex&amp;gt; 2i &amp;lt;/tex&amp;gt; ребер. Итого получаем оценку &amp;lt;tex&amp;gt; 4i &amp;lt;/tex&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Итоговая линейная оценка ==&lt;br /&gt;
&lt;br /&gt;
Оценим время работы алгоритма при использовании всех вышеперечисленных эвристик.&lt;br /&gt;
&lt;br /&gt;
Все неявные продления листов суммарно можно выполнить за &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt; (по Лемме 1)&lt;br /&gt;
По Лемме 2 алгоритм делает не более &amp;lt;tex&amp;gt;2n&amp;lt;/tex&amp;gt; явных продлений. При использовании суффиксных ссылок, как показано в Лемме 5 время на продление равно константе плюс время пропорциональное числу ребер, пройденных при спуске по дереву. Оценим суммарное число таких переходов по ребрам. Первое явное продолжение в любой фазе (кроме первой) начинается с продолжения, которое было последним явным в предыдущей фазе. Поэтому текущаю вершинная глубина не изменяется при переходе к следущей фазе. Как было показано в Лемме 5, каждое продление представляет собой переход не более чем на 2 единицы глубины вверх, а затем несколько переходов вниз, каждый из которых увеличивает глубину на 1. Так как максимальная глубина не превосходит &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;, а количество явных продлений не превышает &amp;lt;tex&amp;gt;2n&amp;lt;/tex&amp;gt;, то по рассуждениям аналогичным Лемме 5 суммарное число таких переходов имеет порядок &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Источник ==&lt;br /&gt;
''Дэн Гасфилд'' — '''Строки, деревья и последовательности в алгоритмах: Информатика и вычислительная биология''' — СПб.: Невский Диалект; БХВ-Петербург, 2003. — 654 с: ил.&lt;br /&gt;
&lt;br /&gt;
[[Категория: Алгоритмы и структуры данных]]&lt;br /&gt;
[[Категория: Словарные структуры данных]]&lt;/div&gt;</summary>
		<author><name>212.193.77.54</name></author>	</entry>

	</feed>