Jump to content

Дерево со сбалансированным весом

В информатике , бинарные деревья со сбалансированным весом ( WBT ) — это тип самобалансирующихся двоичных деревьев поиска которые можно использовать для реализации динамических наборов , словарей (карт) и последовательностей. [1] Эти деревья были представлены Нивергельтом и Рейнгольдом в 1970-х годах как деревья ограниченного баланса , или BB[α]-деревья . [2] [3] Их более распространенное название связано с Кнутом . [4]

Хорошо известным примером является Хаффману кодирование корпуса по .

Как и другие самобалансирующиеся деревья, WBT хранят бухгалтерскую информацию, относящуюся к балансу, в своих узлах и выполняют вращения для восстановления баланса, когда он нарушается операциями вставки или удаления. В частности, каждый узел хранит размер поддерева, корнем которого является узел, а размеры левого и правого поддеревьев сохраняются в пределах некоторого различия друг от друга. В отличие от информации о балансе в деревьях AVL (использующих информацию о высоте поддеревьев) и красно-черных деревьях (которые хранят вымышленный бит «цвета»), информация о балансе в WBT является действительно полезным свойством для приложений: количество элементов в дереве равна размеру его корня, а информация о размере — это именно та информация, которая необходима для реализации операций дерева статистики порядка , а именно: получения n -го по величине элемента в наборе или определения индекса элемента в отсортированный порядок. [5]

Деревья со сбалансированным весом популярны в сообществе функционального программирования и используются для реализации множеств и карт в MIT Scheme , SLIB , SML-NJ и реализациях Haskell . [6] [4]

Описание [ править ]

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

  • ключ любого заказанного типа
  • значение (необязательно, только для сопоставлений)
  • влево , вправо , указатель на узел
  • размер целочисленного типа.

По определению, размер листа (обычно представленного нулевой указатель) равен нулю. Размер внутреннего узла — это сумма размеров двух его дочерних узлов плюс один: ( размер[n] = размер[n.left] + размер[n.right] + 1 ). В зависимости от размера определяется вес, который будет вес[n] = размер[n] + 1 . [а] Преимущество веса состоит в том, что вес узла представляет собой просто сумму весов его левого и правого потомков.

Вращение двоичного дерева .

Операции, которые изменяют дерево, должны гарантировать, что вес левого и правого поддеревьев каждого узла остается в пределах некоторого коэффициента α друг от друга, используя те же операции ребалансировки, которые используются в деревьях AVL : повороты и двойные повороты. Формально баланс узла определяется следующим образом:

Узел является α -весом сбалансированным, если вес[n.left] ≥ α · вес[n] и вес[n.right] ≥ α · вес[n] . [7]

Здесь α — числовой параметр, который необходимо определить при реализации деревьев со сбалансированным весом. Большие значения α создают «более сбалансированные» деревья, но не все значения α подходят; Нивергельт и Рейнгольд доказали, что

является необходимым условием работы алгоритма балансировки. Более поздние работы показали нижнюю границу 2 11 для α , хотя его можно сделать сколь угодно маленьким, если использовать специальный (и более сложный) алгоритм ребалансировки. [7]

Правильное применение балансировки гарантирует, что дерево из n элементов будет иметь высоту. [7]

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

Количество операций балансировки, требуемых в последовательности из n вставок и удалений, линейно по n , т. е. балансировка требует постоянного объема накладных расходов в амортизированном смысле. [8]

Хотя поддержание дерева с минимальной стоимостью поиска требует четырех видов двойных вращений (LL, LR, RL, RR, как в дереве AVL) в операциях вставки/удаления, если нам нужна только логарифмическая производительность, LR и RL являются единственными необходимыми вращениями. за один проход сверху вниз. [9]

Операции с наборами и массовые операции [ править ]

Для деревьев со сбалансированным весом было определено несколько операций над множествами: объединение , пересечение и разность множеств . быстрые массовые Затем на основе этих функций набора можно реализовать операции по вставке или удалению. Эти операции над множествами основаны на двух вспомогательных операциях: Split и Join . Благодаря новым операциям реализация деревьев со сбалансированным весом может стать более эффективной и поддающейся параллелизации. [10] [11]

  • Join : функция Join работает с двумя деревьями со сбалансированным весом t 1 и t 2 и ключом k и возвращает дерево, содержащее все элементы из t 1 , t 2 , а также k . Требуется, чтобы k было больше, чем все ключи в t 1 , и меньше, чем все ключи в t 2 . Если два дерева имеют сбалансированный вес, Join просто создает новый узел с левым поддеревом t 1 , корнем k и правым поддеревом t 2 . Предположим, что t 1 имеет больший вес, чем t 2 (другой случай симметричен). Соединение следует за правым позвоночником t 1 до узла c , который сбалансирован с t 2 . новый узел с левым дочерним элементом c , корнем k и правым дочерним элементом t2 На этом этапе для замены c создается . Новый узел может сделать недействительным инвариант со сбалансированным весом. Это можно исправить с помощью одинарного или двойного поворота, предполагая, что
  • Разделение : чтобы разделить дерево со сбалансированным весом на два меньших дерева: меньшее, чем ключ x , и больше, чем ключ x , сначала нарисуйте путь от корня, вставив x в дерево. После этой вставки все значения меньше x будут найдены слева от пути, а все значения больше x будут найдены справа. Применяя Join , все поддеревья с левой стороны объединяются снизу вверх с использованием ключей на пути в качестве промежуточных узлов снизу вверх, чтобы сформировать левое дерево, а правая часть становится симметричной. Для некоторых приложений Split также возвращает логическое значение, указывающее, присутствует ли x в дереве. Стоимость Сплита , порядок высоты дерева. Этот алгоритм на самом деле не имеет ничего общего с какими-либо особыми свойствами дерева со сбалансированным весом и, таким образом, является общим для других схем балансировки, таких как деревья AVL .

Алгоритм соединения следующий:

функция  joinRightWB(TL  ,  k, T  R  )    (l, k', c) = выставить(  TL  )     if  Balance(|T  L  |, |T  R  |)  return  Node(T  L  , k, T  R  )     еще          Т' = joinRightWB(c, k, T  R  )        (l', k', r') = выставлять(T')         if  (balance(|l|,|T'|))  return  Node(l, k', T')         иначе if  (баланс(|l|,|l'|) и баланс(|l|+|l'|,|r'|))              return  RotateLeft(Node(l, k', T'))         иначе  верните RotateLeft(Node(l, k', RotateRight(T')) функция  joinLeftWB(TL  ,  k, T  R  )    /* симметрично joinRightWB */ функция  join(  TL  , k, T  R  )     if  (heavy(TL  ,  TR  )  ) return joinRightWB(TL  ,  k,  TR  )     if  (heavy(TR  ,  T  L  )) return joinLeftWB(TL  ,  k,  TR  )    Узел(  TL  , k,  TR  ) 

Здесь баланс значит два веса и сбалансированы. Exposure(v)=(l, k, r) означает извлечение узла дерева левый ребенок , ключ узла и правильный ребенок . Node(l, k, r) означает создание узла левого дочернего элемента , ключ и правильный ребенок .

Алгоритм разделения следующий:

функция  разделения (Т, к)     если  (T = ноль) вернуть (ноль, ложь, ноль)    (L, (m, c), R) = выставлять (T)     если  (k = m) вернуть (L, true, R)     если  (к < м)        (L', b, R') = расщепление(L, k)        return  (L', b, join(R', m, R))     если  (к > м)        (L', b, R') = расщепление(R, k)        return  (join(L, m, L'), b, R)) 

Объединение двух сбалансированных по весу деревьев t 1 и t 2, представляющих множества A и B , представляет собой дерево t со сбалансированным по весу , которое представляет A B . Следующая рекурсивная функция вычисляет это объединение:

функция  объединение(т  1  , т  2  ):     если  t  1  = ноль:         вернуть  t  2,      если  t  2  = ноль:         вернуть  т  1     t  <  , t  >  ← разделить t  2  на t  1  .root     return  join(union(left(t  1  ), t  <  ), t  1  .root, Union(right(t  1  ), t  >  )) 

Здесь Split предполагается, что возвращает два дерева: одно содержит ключи, меньшие, чем входной ключ, а другое — более крупные ключи. (Алгоритм неразрушающий , но существует и деструктивная версия.)

Алгоритм пересечения или различия аналогичен, но требует вспомогательной процедуры Join2 , такой же, как и Join , но без среднего ключа. Благодаря новым функциям объединения, пересечения или разности в дерево со сбалансированным весом можно вставлять или удалять один или несколько ключей. Поскольку Split и Union вызывают Join , но не имеют дело непосредственно с критериями балансировки деревьев со сбалансированным весом, такую ​​реализацию обычно называют алгоритмами на основе соединения .

Сложность каждого объединения, пересечения и различия равна для двух сбалансированных по весу деревьев размером и . Эта сложность оптимальна по количеству сравнений. Что еще более важно, поскольку рекурсивные вызовы объединения, пересечения или различия независимы друг от друга, они могут выполняться параллельно с параллельной глубиной. . [10] Когда , реализация на основе соединения имеет тот же вычислительно- ориентированный ациклический граф (DAG), что и одноэлементная вставка и удаление, если корень большего дерева используется для разделения меньшего дерева.

Примечания [ править ]

  1. ^ Это определение использовали Нивергельт и Рейнгольд. Адамс напрямую использует размер как вес, [6] что усложняет анализ его варианта и приводит к ошибкам в основных реализациях. [4]

Ссылки [ править ]

  1. ^ Цакалидис, А.К. (1984). «Поддержание порядка в обобщенном связанном списке». Акта Информатика . 21 : 101–112. дои : 10.1007/BF00289142 . S2CID   26127563 .
  2. ^ Нивергельт, Дж.; Рейнгольд, Э.М. (1973). «Двоичные деревья поиска ограниченного баланса». SIAM Journal по вычислительной технике . 2 : 33–43. дои : 10.1137/0202005 .
  3. ^ Общественное достояние В этой статье использованы общедоступные материалы из Пол Э. Блэк. «Дерево BB(α)» . Словарь алгоритмов и структур данных . НИСТ .
  4. ^ Jump up to: Перейти обратно: а б с Хираи, Ю.; Ямамото, К. (2011). «Балансировка деревьев со сбалансированным весом» (PDF) . Журнал функционального программирования . 21 (3): 287. doi : 10.1017/S0956796811000104 .
  5. ^ Рура, Сальвадор (2001). Новый метод балансировки бинарных деревьев поиска . ИКАЛП . Конспекты лекций по информатике. Том. 2076. стр. 469–480. дои : 10.1007/3-540-48224-5_39 . ISBN  978-3-540-42287-7 .
  6. ^ Jump up to: Перейти обратно: а б Адамс, Стивен (1993). «Функциональные жемчужины: эффективные наборы — баланс» . Журнал функционального программирования . 3 (4): 553–561. дои : 10.1017/S0956796800000885 .
  7. ^ Jump up to: Перейти обратно: а б с Брасс, Питер (2008). Расширенные структуры данных . Издательство Кембриджского университета. стр. 61–71 .
  8. ^ Блюм, Норберт; Мельхорн, Курт (1980). «О среднем количестве операций ребалансировки в деревьях со сбалансированным весом» (PDF) . Теоретическая информатика . 11 (3): 303–320. дои : 10.1016/0304-3975(80)90018-3 .
  9. ^ Чо, Сонхун; Сахни, Сартадж (2000). «Новое бинарное дерево поиска со сбалансированным весом» . Международный журнал основ компьютерных наук . 11 (3): 485–513. CiteSeerX   10.1.1.36.3888 . дои : 10.1142/S0129054100000296 .
  10. ^ Jump up to: Перейти обратно: а б Блеллок, Гай Э.; Феризович, Дэниел; Сунь, Ихан (2016), «Просто присоединяйтесь к параллельным упорядоченным наборам», Симпозиум по параллельным алгоритмам и архитектурам, Proc. 28-го симпозиума ACM. Параллельные алгоритмы и архитектуры (SPAA 2016) , ACM, стр. 253–264, arXiv : 1602.02120 , doi : 10.1145/2935764.2935768 , ISBN  978-1-4503-4210-0 , S2CID   2897793 .
  11. ^ Адамс, Стивен (1992), Эффективная реализация множеств на функциональном языке , CiteSeerX   10.1.1.501.8427 .
Arc.Ask3.Ru: конец переведенного документа.
Arc.Ask3.Ru
Номер скриншота №: d416b8eac2efdf804eb6e327903243fd__1717529580
URL1:https://arc.ask3.ru/arc/aa/d4/fd/d416b8eac2efdf804eb6e327903243fd.html
Заголовок, (Title) документа по адресу, URL1:
Weight-balanced tree - Wikipedia
Данный printscreen веб страницы (снимок веб страницы, скриншот веб страницы), визуально-программная копия документа расположенного по адресу URL1 и сохраненная в файл, имеет: квалифицированную, усовершенствованную (подтверждены: метки времени, валидность сертификата), открепленную ЭЦП (приложена к данному файлу), что может быть использовано для подтверждения содержания и факта существования документа в этот момент времени. Права на данный скриншот принадлежат администрации Ask3.ru, использование в качестве доказательства только с письменного разрешения правообладателя скриншота. Администрация Ask3.ru не несет ответственности за информацию размещенную на данном скриншоте. Права на прочие зарегистрированные элементы любого права, изображенные на снимках принадлежат их владельцам. Качество перевода предоставляется как есть. Любые претензии, иски не могут быть предъявлены. Если вы не согласны с любым пунктом перечисленным выше, вы не можете использовать данный сайт и информация размещенную на нем (сайте/странице), немедленно покиньте данный сайт. В случае нарушения любого пункта перечисленного выше, штраф 55! (Пятьдесят пять факториал, Денежную единицу (имеющую самостоятельную стоимость) можете выбрать самостоятельно, выплаичвается товарами в течение 7 дней с момента нарушения.)