<?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=Lex4051</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=Lex4051"/>
		<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/Lex4051"/>
		<updated>2026-06-11T13:57:33Z</updated>
		<subtitle>Вклад участника</subtitle>
		<generator>MediaWiki 1.30.0</generator>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A0%D0%B0%D0%BD%D0%B4%D0%BE%D0%BC%D0%B8%D0%B7%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%BD%D0%BE%D0%B5_%D0%B1%D0%B8%D0%BD%D0%B0%D1%80%D0%BD%D0%BE%D0%B5_%D0%B4%D0%B5%D1%80%D0%B5%D0%B2%D0%BE_%D0%BF%D0%BE%D0%B8%D1%81%D0%BA%D0%B0&amp;diff=30557</id>
		<title>Рандомизированное бинарное дерево поиска</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A0%D0%B0%D0%BD%D0%B4%D0%BE%D0%BC%D0%B8%D0%B7%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%BD%D0%BE%D0%B5_%D0%B1%D0%B8%D0%BD%D0%B0%D1%80%D0%BD%D0%BE%D0%B5_%D0%B4%D0%B5%D1%80%D0%B5%D0%B2%D0%BE_%D0%BF%D0%BE%D0%B8%D1%81%D0%BA%D0%B0&amp;diff=30557"/>
				<updated>2013-03-03T01:28:19Z</updated>
		
		<summary type="html">&lt;p&gt;Lex4051: /* Вставка */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Рандомизированное бинарное дерево поиска (англ. ''Randomized binary search tree'', RBST) {{---}} структура данных, реализующая бинарное дерево поиска.&lt;br /&gt;
&lt;br /&gt;
==Основная идея и связанные определения==&lt;br /&gt;
Как известно, можно подобрать такую последовательность операций с [[Дерево поиска, наивная реализация|бинарным деревом поиска в наивной реализации]], что его глубина будет пропорциональна количеству ключей, а следовательно запрос будет выполняться за &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt;. Поэтому, если поддерживать инвариант &amp;quot;случайности&amp;quot; в дереве, то можно добиться того, что математическое ожидание глубины дерева будет небольшим.&lt;br /&gt;
Дадим рекурсивное определение '''рандомизированного бинарного дерева поиска (RBST)'''.&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; {{---}} бинарное дерево поиска. Тогда&lt;br /&gt;
# Если &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; пусто, то оно является рандомизированным бинарным деревом поиска.&lt;br /&gt;
# Если &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; непусто (содержит &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; вершин, &amp;lt;tex&amp;gt;n &amp;gt; 0&amp;lt;/tex&amp;gt;), то &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; {{---}} рандомизированное бинарное дерево поиска тогда и только тогда, когда его левое и правое поддеревья (&amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;R&amp;lt;/tex&amp;gt;) оба являются RBST, а также выполняется соотношение&lt;br /&gt;
&amp;lt;tex&amp;gt;P[size(L) = i] = \frac{1}n, i = 1..n&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
Из определения следует, что каждый ключ в RBST размера n может оказаться корнем с вероятностью 1/n.&lt;br /&gt;
&lt;br /&gt;
Идея RBST состоит в том, что хранимое дерево постоянно является рандомизированным бинарным деревом поиска. Далее подробно будет описана реализация операций над RBST, которая позволит добиться этой цели. Заметим лишь, что хранение RBST в памяти ничем не отличается от хранения обычного дерева поиска: хранится указатель на корень; в каждой вершине хранятся указатели на её сыновей.&lt;br /&gt;
 &lt;br /&gt;
(Похожие идеи используются в [[Декартово дерево| декартовом дереве]], поэтому во многих русскоязычных ресурсах термин '''рандомизированное бинарное дерево поиска''' используется как синонимическое название декартового дерева и [[Декартово дерево по неявному ключу|декартового дерева по неявному ключу]])&lt;br /&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;x&amp;lt;/tex&amp;gt; в RBST, состоящее из &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; вершин. С вероятностью &amp;lt;tex dpi = &amp;quot;150&amp;quot;&amp;gt;\frac{1}{n+1}&amp;lt;/tex&amp;gt; вставим ключ в корень дерева, используя процедуру ''insert_at_root''. С вероятностью &amp;lt;tex dpi = &amp;quot;150&amp;quot;&amp;gt;1 - \frac{1}{n+1} = \frac{n}{n+1}&amp;lt;/tex&amp;gt; вставим его в правое поддерево, если он больше корня, или в левое поддерево, если меньше. Ниже приведён псевдокод процедуры вставки ''insert'', процедуры ''insert_at_root'', а также процедуры ''split(k)'', разбивающей дерево на два поддерева, в одном из которых все ключи строго меньше &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;, а в другом больше, либо равны; приведена достаточно очевидная рекурсивная реализация. (через Node обозначен тип вершины дерева, дерево представляется как указатель на корень)&lt;br /&gt;
&lt;br /&gt;
 '''Node''' '''insert''' (T, x)&lt;br /&gt;
    '''int''' r = '''random'''(0..size(T))&lt;br /&gt;
    '''if''' (r == n)&lt;br /&gt;
       T = insert_at_root(T, x)&lt;br /&gt;
    '''if''' (x &amp;lt; root.key)&lt;br /&gt;
       T = insert(T.left, x)&lt;br /&gt;
    '''else'''&lt;br /&gt;
       T = insert(T.right, x)&lt;br /&gt;
    '''return''' T&lt;br /&gt;
&lt;br /&gt;
Заметим, что если дерево пусто, то ''insert'' с вероятностью 1 делает &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; корнем.&lt;br /&gt;
&lt;br /&gt;
 // вставляет ключ x в дерево T&lt;br /&gt;
 '''Node''' '''insert_at_root''' (T, x)&lt;br /&gt;
    // создать пустые L и R&lt;br /&gt;
    L = RBST()&lt;br /&gt;
    R = RBST()&lt;br /&gt;
    split(T, x, L, R)&lt;br /&gt;
    // создать пустое T&lt;br /&gt;
    T = RBST()&lt;br /&gt;
    T.key = x&lt;br /&gt;
    T.left = L&lt;br /&gt;
    T.left = R&lt;br /&gt;
    '''return''' T&lt;br /&gt;
&lt;br /&gt;
 // разделяет дерево T по x&lt;br /&gt;
 // результат: деревья L и R&lt;br /&gt;
 '''split''' (T, x, L, R)&lt;br /&gt;
    '''if''' (size(T) == 0)&lt;br /&gt;
       // создать пустые L и R&lt;br /&gt;
       L = RBST()&lt;br /&gt;
       R = RBST()&lt;br /&gt;
    '''else''' '''if''' (x &amp;lt; T.key)&lt;br /&gt;
       R = T&lt;br /&gt;
       split (T.left, x, L, R.left)&lt;br /&gt;
    '''else'''&lt;br /&gt;
       L = T&lt;br /&gt;
       split (T.right, x, L.right, R)&lt;br /&gt;
&lt;br /&gt;
Далее рассмотрим как меняется свойство дерева быть рандомизированным при вставке в него ключей.&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement= Пусть после операции ''split'' от дерева &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; по ключу &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; были получены деревья &amp;lt;tex&amp;gt;T_{L}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;T_{R}&amp;lt;/tex&amp;gt;. Тогда если &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; было рандомизированным бинарным деревом поиска, содержащим множество ключей &amp;lt;tex&amp;gt;K&amp;lt;/tex&amp;gt;, то деревья &amp;lt;tex&amp;gt;T_{L}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;T_{R}&amp;lt;/tex&amp;gt; {{---}} рандомизированные бинарные деревья поиска, содержащие соответственно множества ключей &amp;lt;tex&amp;gt;K_{L} = \{y \in K | y &amp;lt; x\}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;K_{R} = \{y \in K | y &amp;gt; x\}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|proof=&lt;br /&gt;
Применим индукцию по &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; {{---}} размеру дерева. Если &amp;lt;tex&amp;gt;n = 0&amp;lt;/tex&amp;gt;, то лемма верна (получим два пустых дерева).&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;n &amp;gt; 0&amp;lt;/tex&amp;gt;, и лемма верна при всех меньших размерах дерева.. Пусть также &amp;lt;tex&amp;gt;y = T.key, L = T.left, R = T.right&amp;lt;/tex&amp;gt;. Если &amp;lt;tex&amp;gt;x &amp;gt; y&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; {{---}} корень &amp;lt;tex&amp;gt;T_{L}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; {{---}} левое поддерево &amp;lt;tex&amp;gt;T_{L}&amp;lt;/tex&amp;gt;, а ''split'' рекурсивно вызовется от &amp;lt;tex&amp;gt;R&amp;lt;/tex&amp;gt;, разделив его на &amp;lt;tex&amp;gt;R'&amp;lt;/tex&amp;gt; {{---}} правое поддерево &amp;lt;tex&amp;gt;T_{L}&amp;lt;/tex&amp;gt; {{---}}, и &amp;lt;tex&amp;gt;T_{R}&amp;lt;/tex&amp;gt;, которые по предположению индукции будут рандомизированными бинарными деревьями поиска. Но &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; также является RBST, т.к. является поддеревом &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Итак для того, чтобы доказать, что &amp;lt;tex&amp;gt;T_{L}&amp;lt;/tex&amp;gt; {{---}} рандомизированное бинарное дерево поиска, осталось показать, что любая его вершина &amp;lt;tex&amp;gt;z&amp;lt;/tex&amp;gt; с вероятностью &amp;lt;tex dpi = &amp;quot;150&amp;quot;&amp;gt;\frac{1}{m}&amp;lt;/tex&amp;gt; окажется в корне, где &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; {{---}} размер &amp;lt;tex&amp;gt;T_{L}&amp;lt;/tex&amp;gt;. Действительно:&lt;br /&gt;
&lt;br /&gt;
(пусть событие &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; {{---}} &amp;lt;tex&amp;gt;z&amp;lt;/tex&amp;gt; является коренем &amp;lt;tex&amp;gt;T_{L}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex dpi = &amp;quot;150&amp;quot;&amp;gt;P[A | y &amp;lt; x] = \frac{P[A \; \wedge \; y &amp;lt; x]}{P[y &amp;lt; x]} = \frac{1 / n}{m / n} = \frac{1}{m}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Случай, когда &amp;lt;tex&amp;gt;x &amp;lt; y&amp;lt;/tex&amp;gt; симметричен рассмотренному.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Теорема &lt;br /&gt;
|statement= Если &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; {{---}} рандомизированное бинарное дерево поиска, содержащее множество ключей &amp;lt;tex&amp;gt;K&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;x \notin K&amp;lt;/tex&amp;gt;, тогда процедура ''insert(x, T)'' вернёт рандомизированное бинарное дерево поиска &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, содержащее множество ключей &amp;lt;tex&amp;gt;K \cap x&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|proof=&lt;br /&gt;
Применим индукцию по &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; {{---}} размеру дерева. Если &amp;lt;tex&amp;gt;n = 0&amp;lt;/tex&amp;gt;, то теорема верна: после операции ''insert(x, T)'' получим дерево с корнем &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и двумя пустыми поддеревьями.&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;n &amp;gt; 0&amp;lt;/tex&amp;gt;, и теорема верна при всех меньших размерах дерева. Возможны два случая: &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; вставляется в корень или рекурсивно в одно из поддеревьев.&lt;br /&gt;
&lt;br /&gt;
В первом случае правое и левое поддеревья &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; по лемме являются рандомизированными BST, а также вероятность того, что &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; окажется в корне, равна &amp;lt;tex dpi = &amp;quot;150&amp;quot;&amp;gt;\frac{1}{n + 1}&amp;lt;/tex&amp;gt;. Т.е. новое дерево {{---}} рандомизированное BST.&lt;br /&gt;
&lt;br /&gt;
Во втором случае корень у дерева останется прежнем. Заметим, что для каждого &amp;lt;tex&amp;gt;y \in K&amp;lt;/tex&amp;gt; вероятность быть корнем была &amp;lt;tex dpi = &amp;quot;150&amp;quot;&amp;gt;\frac{1}{n}&amp;lt;/tex&amp;gt;, а корнем он останется с вероятностью &amp;lt;tex dpi = &amp;quot;150&amp;quot;&amp;gt;\frac{n}{n + 1}&amp;lt;/tex&amp;gt;, тогда для каждого &amp;lt;tex&amp;gt;y \in K&amp;lt;/tex&amp;gt; вероятность быть корнем равна &amp;lt;tex dpi = &amp;quot;150&amp;quot;&amp;gt;\frac{1}{n} \cdot \frac{n}{n + 1} = \frac{1}{n + 1}&amp;lt;/tex&amp;gt;. По предположению же индукции поддерево, в которое вставляется &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; становится рандомизированным бинарным деревом поиска; а т.к. другое поддерево корня было рандомизированным, то новое дерево {{---}} рандомизированное BST.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;K = \{x_{1}, ... ,x_{n}\}&amp;lt;/tex&amp;gt; {{---}} множество ключей, &amp;lt;tex&amp;gt;P = \{x_{i_{1}}, ... ,x_{i_{n}}\}&amp;lt;/tex&amp;gt; {{---}} какая-то фиксированная перестановка элементов &amp;lt;tex&amp;gt;K&amp;lt;/tex&amp;gt;. Из приведённой выше теоремы следует, что если в изначально пустое дерево &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; добавлять ключи P по порядку, то получим дерево &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, являющееся RBST.&lt;br /&gt;
&lt;br /&gt;
===Удаление===&lt;br /&gt;
&lt;br /&gt;
Алгоритм удаления использует операцию ''merge'' {{---}} слияние двух деревьев, удовлетворяющих условию: все ключи в одном из деревьев меньше ключей во втором. Для того, чтобы удалить некоторый ключ &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; из RBST сначала найдём вершину с этим ключом в дереве, используя стандартный алгоритм поиска. Если вершина не найдена, то выходим из алгоритма; в противном случае сливаем правое и левое поддеревья &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; (заметим, что ключи в левом поддереве меньше ключей в правом), удаляем &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;, а корень образовавшегося дерева делаем новым сыном родителя &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;. Псевдокод процедур удаления и слияния приведён ниже.&lt;br /&gt;
&lt;br /&gt;
 // удаляет ключ x из дерева T&lt;br /&gt;
 '''Node''' '''remove'''(T, x)&lt;br /&gt;
    '''if''' (size(T) == 0)&lt;br /&gt;
       // выйти, вернув пустое дерево&lt;br /&gt;
       T = RBST()&lt;br /&gt;
       '''return''' T&lt;br /&gt;
    '''if''' (x &amp;lt; T.key)&lt;br /&gt;
       T.left = remove(T.left, x)&lt;br /&gt;
    '''else''' '''if''' (x &amp;gt; T.key)&lt;br /&gt;
       T.right = remove(T.right, x)&lt;br /&gt;
    '''else'''&lt;br /&gt;
       // создать пустое дерево Q&lt;br /&gt;
       Q = RBST()&lt;br /&gt;
       Q = merge(T.left, T.right)&lt;br /&gt;
       T = Q&lt;br /&gt;
    '''return''' T&lt;br /&gt;
&lt;br /&gt;
 // сливает деревья L и R&lt;br /&gt;
 // результат: дерево T&lt;br /&gt;
 '''Node''' '''merge'''(L, R)&lt;br /&gt;
    '''int''' m = L.size&lt;br /&gt;
    '''int''' n = R.size&lt;br /&gt;
    '''int''' total = m + n&lt;br /&gt;
    '''if''' (total == 0)&lt;br /&gt;
       // вернуть пустое T&lt;br /&gt;
       T = RBST()&lt;br /&gt;
       '''return''' T&lt;br /&gt;
    '''int''' r = random(1..total)&lt;br /&gt;
    '''if''' (r &amp;lt; m)&lt;br /&gt;
       // с вероятностью m / (m + n)&lt;br /&gt;
       L.right = merge(L.right, R)&lt;br /&gt;
       '''return''' L&lt;br /&gt;
    '''if''' (r &amp;lt; m)&lt;br /&gt;
       // с вероятностью m / (m + n)&lt;br /&gt;
       R.left = merge(L, R.left)&lt;br /&gt;
       '''return''' R&lt;br /&gt;
&lt;br /&gt;
Докажем, что данный алгоритм оставляет рандомизированное дерево рандомизированным.&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement= Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;R&amp;lt;/tex&amp;gt; {{---}} рандомизированные бинарные деревья поиска, содержащие соответственно множества ключей &amp;lt;tex&amp;gt;K_{L}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;K_{R}&amp;lt;/tex&amp;gt;, причём &amp;lt;tex&amp;gt;K_{L} &amp;lt; K_{R}&amp;lt;/tex&amp;gt; (то есть каждый элемент &amp;lt;tex&amp;gt;K_{L}&amp;lt;/tex&amp;gt; меньше каждого элемента &amp;lt;tex&amp;gt;K_{R}&amp;lt;/tex&amp;gt;). Тогда операция ''merge(L, R)'' вернёт рандомизированное бинарное дерево поиска, содержащее множество ключей &amp;lt;tex&amp;gt;K&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;K_{L} \cap K_{R}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|proof=&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; {{---}} размеры &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;R&amp;lt;/tex&amp;gt; соответственно. Применим индукцию по &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;. Если &amp;lt;tex&amp;gt;m = 0&amp;lt;/tex&amp;gt; или &amp;lt;tex&amp;gt;n = 0&amp;lt;/tex&amp;gt;, то лемма верна.&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;m &amp;gt; 0&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;n &amp;gt; 0&amp;lt;/tex&amp;gt;, пусть также &amp;lt;tex&amp;gt;L.key = a&amp;lt;/tex&amp;gt; или &amp;lt;tex&amp;gt;L.key = b&amp;lt;/tex&amp;gt;. Без потери общности делаем корнем &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt;. После рекурсивного слияния правого поддерева &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;R&amp;lt;/tex&amp;gt; получим рандомизированное бинарное дерево поиска (которое является правым поддеревом нового дерева). Левое же поддерево нового дерева тоже рандомизированное. Также верно, что для любого &amp;lt;tex&amp;gt;x \in K_{L}&amp;lt;/tex&amp;gt; вероятность быть корнем равна &amp;lt;tex dpi = &amp;quot;150&amp;quot;&amp;gt;\frac{1}{m + n}&amp;lt;/tex&amp;gt;: действительно, вероятность оказаться в корне в &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; до слияния равна &amp;lt;tex dpi = &amp;quot;150&amp;quot;&amp;gt;\frac{1}{m}&amp;lt;/tex&amp;gt;, вероятность того, что элемент останется корнем после слияния равна &amp;lt;tex dpi = &amp;quot;150&amp;quot;&amp;gt;\frac{m}{m + n}&amp;lt;/tex&amp;gt;; осталось применить правило умножения.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Теорема &lt;br /&gt;
|statement= Если &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; {{---}} рандомизированное бинарное дерево поиска, содержащее множество ключей &amp;lt;tex&amp;gt;K&amp;lt;/tex&amp;gt;, тогда процедура ''remove(x, T)'' вернёт рандомизированное бинарное дерево поиска &amp;lt;tex&amp;gt;T'&amp;lt;/tex&amp;gt;, содержащее множество ключей &amp;lt;tex&amp;gt;K \backslash \{x\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
|proof=&lt;br /&gt;
Если удаляемый элемент отсутствует в дереве, то теорема верна.&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;x \in T&amp;lt;/tex&amp;gt; (дерево не пусто), &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; {{---}} размер &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;. Докажем теорему по индукции по &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;. Для &amp;lt;tex&amp;gt;n = 1&amp;lt;/tex&amp;gt; теорема очевидным образом верна. Пусть &amp;lt;tex&amp;gt;n &amp;gt; 1&amp;lt;/tex&amp;gt;, и предположим, что теорема верна для всех деревьев размера меньше &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Возможно два случая: если &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; {{---}} корень &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, то по лемме, после удаления получим рандомизированное бинарное дерево поиска; если же &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; {{---}} не корень &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; рекурсивно удаляется из поддерева исходного дерева, и по предположению индукции после удаления получаем рандомизированное BST. Осталось лишь показать, что для любого &amp;lt;tex&amp;gt;y \in T, y \neq x&amp;lt;/tex&amp;gt; вероятность оказаться корнем после удаления равна &amp;lt;tex dpi = &amp;quot;150&amp;quot;&amp;gt;\frac{1}{n - 1}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Введём обозначения:&lt;br /&gt;
&lt;br /&gt;
событие &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; {{---}} &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; является коренем &amp;lt;tex&amp;gt;T'&amp;lt;/tex&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
событие &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; {{---}} &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; был корнем &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; (до операции ''remove'');&lt;br /&gt;
&lt;br /&gt;
событие &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; {{---}} &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; стал корнем &amp;lt;tex&amp;gt;T'&amp;lt;/tex&amp;gt; после операции ''merge'' (но до этого им не являлся);&lt;br /&gt;
&lt;br /&gt;
событие &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; {{---}} &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; был корнем &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; (до операции ''remove'');&lt;br /&gt;
&lt;br /&gt;
Тогда:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;P[A] = P[A|B] \times P[B] + P[A|\neg B] \times P[\neg B] = P[C] \times 1/n + P[D|\neg B] \times (n - 1)/n = &amp;lt;/tex&amp;gt;&lt;br /&gt;
&amp;lt;tex dpi = &amp;quot;150&amp;quot;&amp;gt;\frac{1}{n - 1} \times \frac{1}{n} + \frac{1}{n - 1} \times \frac{n - 1}{n} = \frac{1}{n - 1}&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;O (\log n)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; {{---}} число вершин в дереве, то математическое ожидание времени работы поиска, вставки и удаления {{---}} также &amp;lt;tex&amp;gt;O (\log n)&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;
==Ссылки==&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Treap Википедия {{---}} Дерамида и RBST]&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Random_binary_tree Википедия {{---}} случайное бинарное дерево]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
* Martinez, Conrado; Roura, Salvador (1997), &amp;quot;Randomized binary search trees&amp;quot;, Journal of the ACM 45&lt;br /&gt;
* Seidel, Raimund; Aragon, Cecilia R. [http://people.ischool.berkeley.edu/~aragon/pubs/rst96.pdf «Randomized Search Trees»], 1996 г.&lt;br /&gt;
* [http://www.cs.uiuc.edu/class/sp09/cs473/notes/08-treaps.pdf Randomized binary search trees]. Lecture notes from a course by Jeff Erickson at UIUC.&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория: Деревья поиска]]&lt;/div&gt;</summary>
		<author><name>Lex4051</name></author>	</entry>

	</feed>