<?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=138.197.174.51&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=138.197.174.51&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/138.197.174.51"/>
		<updated>2026-05-19T16:45:45Z</updated>
		<subtitle>Вклад участника</subtitle>
		<generator>MediaWiki 1.30.0</generator>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9B%D0%B5%D0%B2%D0%BE%D1%81%D1%82%D0%BE%D1%80%D0%BE%D0%BD%D0%BD%D0%B8%D0%B5_%D0%BA%D1%80%D0%B0%D1%81%D0%BD%D0%BE-%D1%87%D1%91%D1%80%D0%BD%D1%8B%D0%B5_%D0%B4%D0%B5%D1%80%D0%B5%D0%B2%D1%8C%D1%8F&amp;diff=65242</id>
		<title>Левосторонние красно-чёрные деревья</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9B%D0%B5%D0%B2%D0%BE%D1%81%D1%82%D0%BE%D1%80%D0%BE%D0%BD%D0%BD%D0%B8%D0%B5_%D0%BA%D1%80%D0%B0%D1%81%D0%BD%D0%BE-%D1%87%D1%91%D1%80%D0%BD%D1%8B%D0%B5_%D0%B4%D0%B5%D1%80%D0%B5%D0%B2%D1%8C%D1%8F&amp;diff=65242"/>
				<updated>2018-05-04T22:04:20Z</updated>
		
		<summary type="html">&lt;p&gt;138.197.174.51: /* Исправление правых красных связей */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Определение&lt;br /&gt;
|definition =  Левосторонние красно-черные деревья {{---}} модификация [[Красно-черное дерево|красно-черных деревьев]], имеющая ряд преимуществ на классической структурой. Разработана Робертом Соджевиском в &amp;lt;tex&amp;gt;2008&amp;lt;/tex&amp;gt; году.&lt;br /&gt;
  }}&lt;br /&gt;
==Преимущества==&lt;br /&gt;
* необходимо менее &amp;lt;tex&amp;gt;80&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;
Из этих инвариантов следует, что длина каждого пути от корня до листьев в красно-черном дереве с &amp;lt;tex&amp;gt;N&amp;lt;/tex&amp;gt; узлами не превышает &amp;lt;tex&amp;gt;2 \cdot \log(N)&amp;lt;/tex&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
Основные операции, используемые алгоритмами сбалансированного дерева для поддержания баланса при вставке и удалении, называются вращениями. Эти операции трансформируют &amp;lt;tex&amp;gt;3&amp;lt;/tex&amp;gt;-узел,левый потомок которого окрашен в красный, в  &amp;lt;tex&amp;gt;3&amp;lt;/tex&amp;gt;-узел, правый потомок которого окрашен в красный и наоборот.  Вращения сохраняют два указанных выше инварианта, не изменяют поддеревья узла.&lt;br /&gt;
===Псевокод===&lt;br /&gt;
[[File:rotateRight.png|310px|thumb|upright|Rotate Right]]&lt;br /&gt;
   '''Node''' rotateRight( h : '''Node''') :&lt;br /&gt;
       x = h.left&lt;br /&gt;
       h.left= x.right&lt;br /&gt;
       x.right= h&lt;br /&gt;
       x.color = h.color&lt;br /&gt;
       h.color = RED&lt;br /&gt;
    '''return''' x&lt;br /&gt;
[[File:rotateLeft.png|310px|thumb|upright|Rotate Left]]&lt;br /&gt;
   '''Node''' rotateLeft( h : '''Node''') :&lt;br /&gt;
       x = h.right&lt;br /&gt;
       h.right = x.left&lt;br /&gt;
       x.left = h&lt;br /&gt;
       x.color = h.color&lt;br /&gt;
       h.color = RED&lt;br /&gt;
   '''return''' x&lt;br /&gt;
&lt;br /&gt;
==Переворот цветов==&lt;br /&gt;
&lt;br /&gt;
В красно-черных деревьях используется такая  операция как '''Переворот цветов''' &amp;lt;tex&amp;gt;(flip color)&amp;lt;/tex&amp;gt; , которая инвертирует цвет узла и двух его детей.  Она не изменяет количество черных узлов  при любом обходе от корня до листьев дерева, но может привести к появлению двух последовательных красных узлов. &lt;br /&gt;
[[File: ColorFlip.png|320px|thumb|upright| Color Flip]]&lt;br /&gt;
&lt;br /&gt;
  '''void''' flipColors( h : '''Node''' h) :&lt;br /&gt;
       h.color = '''!''' h.color&lt;br /&gt;
       h.left.color =  '''!''' h.left.color&lt;br /&gt;
       h.right.color = &amp;lt;tex&amp;gt; !&amp;lt;/tex&amp;gt; h.right.color&lt;br /&gt;
&lt;br /&gt;
==Вставка==&lt;br /&gt;
Вставка в ЛСКЧД базируется на &amp;lt;tex&amp;gt;4&amp;lt;/tex&amp;gt; простых операциях:&lt;br /&gt;
&lt;br /&gt;
*Вставка нового узла к листу дерева:&lt;br /&gt;
[[File:insertNode.png|310px|thumb|upright|Вставка нового узла]]&lt;br /&gt;
&lt;br /&gt;
  if (h == null)&lt;br /&gt;
       return new Node(key, value, RED);&lt;br /&gt;
&lt;br /&gt;
*Расщепление узла с &amp;lt;tex&amp;gt;4&amp;lt;/tex&amp;gt;-я потомками:&lt;br /&gt;
[[File:Split4node.png|310px|thumb|upright|Расщепление узла]]&lt;br /&gt;
  if (isRed(h.left) &amp;amp;&amp;amp; isRed(h.right))&lt;br /&gt;
      colorFlip(h);&lt;br /&gt;
&lt;br /&gt;
*Принудительное вращение влево:&lt;br /&gt;
[[File:Enforce.png|310px|thumb|upright|Принудительное вращение]]&lt;br /&gt;
  if (isRed(h.right))&lt;br /&gt;
      h = rotateLeft(h);&lt;br /&gt;
&lt;br /&gt;
*Балансировка узла с &amp;lt;tex&amp;gt;4&amp;lt;/tex&amp;gt;-я потомками:&lt;br /&gt;
[[File:Balance4node.png|310px|thumb|Балансировка]]&lt;br /&gt;
  if (isRed(h.left) &amp;amp;&amp;amp; isRed(h.left.left))&lt;br /&gt;
      h = rotateRight(h);&lt;br /&gt;
   &lt;br /&gt;
===Псевдокод===&lt;br /&gt;
  '''void''' insert( '''key''' : Key, '''value''' : Value ): &lt;br /&gt;
         root = insert(root, key, value)&lt;br /&gt;
         root.color = BLACK&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  '''Node''' insert( h : '''Node''', key : '''Key''', value : '''Value'''):&lt;br /&gt;
      //Вставка нового узла к листу дерева&lt;br /&gt;
      '''if''' h == ''null''     &lt;br /&gt;
          '''return''' '''new''' Node(key, value)&lt;br /&gt;
      //Расщепление узла с &amp;lt;tex&amp;gt;4&amp;lt;/tex&amp;gt;-я потомками&lt;br /&gt;
      '''if''' isRed(h.left) '''&amp;amp;&amp;amp;''' isRed(h.right)&lt;br /&gt;
          colorFlip(h)&lt;br /&gt;
      //Стандартная вставка [[Дерево поиска, наивная реализация|в дереве поиска]]&lt;br /&gt;
      '''int''' cmp = key.compareTo(h.key) &lt;br /&gt;
      '''if'''  cmp == 0&lt;br /&gt;
          h.val = value&lt;br /&gt;
      '''else''' &lt;br /&gt;
          '''if''' cmp &amp;lt; 0 &lt;br /&gt;
              h.left = insert(h.left, key, value)  &lt;br /&gt;
          '''else''' &lt;br /&gt;
              h.right = insert(h.right, key, value)&lt;br /&gt;
          //Принудительное вращение влево&lt;br /&gt;
          '''if''' isRed(h.right) '''&amp;amp;&amp;amp;''' '''!'''isRed(h.left)    &lt;br /&gt;
              h = rotateLeft(h)&lt;br /&gt;
          ////Балансировка узла с &amp;lt;tex&amp;gt;4&amp;lt;/tex&amp;gt;-я потомками&lt;br /&gt;
          '''if''' isRed(h.left) '''&amp;amp;&amp;amp;''' isRed(h.left.left)&lt;br /&gt;
              h = rotateRight(h)&lt;br /&gt;
  '''return''' ''h''&lt;br /&gt;
&lt;br /&gt;
==Поиск==&lt;br /&gt;
Поиск в левосторонних красно-черных деревьях эквивалентен поиску в [[Дерево поиска, наивная реализация|наивной реализации дерева поиска]].&lt;br /&gt;
===Псевдокод===&lt;br /&gt;
 '''Value''' search(key : '''Key'''):&lt;br /&gt;
     '''Node''' x = root&lt;br /&gt;
     '''while''' (x '''!'''= null)&lt;br /&gt;
       '''int''' cmp = key.compareTo(x.key)&lt;br /&gt;
       '''if''' (cmp == 0)&lt;br /&gt;
           '''return''' x.val&lt;br /&gt;
       '''else'''&lt;br /&gt;
           '''if''' (cmp &amp;lt; 0)&lt;br /&gt;
               x = x.left&lt;br /&gt;
       '''else''' &lt;br /&gt;
           '''if''' (cmp &amp;gt; 0) &lt;br /&gt;
               x = x.right&lt;br /&gt;
 '''return''' ''null''&lt;br /&gt;
&lt;br /&gt;
==Удаление==&lt;br /&gt;
===Исправление правых красных связей===&lt;br /&gt;
*Использование Переворота цветов и вращений  сохраняет баланс черной связи.&lt;br /&gt;
*После удаления необходимо исправить правые красные связи и устранить узлы с &amp;lt;tex&amp;gt;4-&amp;lt;/tex&amp;gt;я потомками&lt;br /&gt;
      //Исправление правых красных связей&lt;br /&gt;
   '''Node''' fixUp(h : '''Node'''){&lt;br /&gt;
       '''if''' (isRed(h.right))&lt;br /&gt;
           h = rotateLeft(h);&lt;br /&gt;
      //Вращение &amp;lt;tex&amp;gt;red-red&amp;lt;/tex&amp;gt; пары&lt;br /&gt;
       '''if''' (isRed(h.left) '''&amp;amp;&amp;amp;''' isRed(h.left.left))&lt;br /&gt;
           h = rotateRight(h);&lt;br /&gt;
      //Балансировка узла с &amp;lt;tex&amp;gt;4&amp;lt;/tex&amp;gt;-я потомками&lt;br /&gt;
       '''if''' (isRed(h.left) '''&amp;amp;&amp;amp;''' isRed(h.right))&lt;br /&gt;
           colorFlip(h);&lt;br /&gt;
   '''return''' h; &lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
===Удаление максимума===&lt;br /&gt;
* Спускаемся вниз по правому краю  дерева.&lt;br /&gt;
* Если поиск заканчивается на узле с &amp;lt;tex&amp;gt;4&amp;lt;/tex&amp;gt;-мя или &amp;lt;tex&amp;gt;5&amp;lt;/tex&amp;gt;-ю потомками, просто удаляем узел.&lt;br /&gt;
&lt;br /&gt;
[[File:34-nodeRemove.png|310px|thumb|center| Узлы до и после удаления]] &lt;br /&gt;
* Удаление узла с &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;gt;-я потомками разрушает баланс&lt;br /&gt;
Соответственно спускаясь вниз по дереву необходимо поддерживать следующий инвариант : количество потомков узла не должно быть ровно &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;gt;-м.&lt;br /&gt;
[[File:changeNode.png|600px|thumb|center| ]] &lt;br /&gt;
 &lt;br /&gt;
Будем поддерживать инвариант : Для любого узла либо сам узел, либо правый предок узла '''красный'''.&lt;br /&gt;
Будем придерживаться тактики , что удалять лист легче, чем внутренний узел.&lt;br /&gt;
&lt;br /&gt;
Заметим, что если правый потомок вершины и правый потомок правого потомка вершины черные, необходимо переместить левую красную ссылку вправо для сохранения инварианта.&lt;br /&gt;
[[File:MinEasy.png|400px|thumb|right| Перемещение красной ссылки. Простой случай]] &lt;br /&gt;
&lt;br /&gt;
[[File:MinHard.png|400px|thumb|right| Перемещение красной ссылки. Сложный случай]]&lt;br /&gt;
&lt;br /&gt;
===Псевдокод===&lt;br /&gt;
 '''void''' deleteMax()&lt;br /&gt;
     root = deleteMax(root);&lt;br /&gt;
     root.color = BLACK;&lt;br /&gt;
&lt;br /&gt;
 '''Node''' moveRedLeft(h : '''Node''')&lt;br /&gt;
     colorFlip(h);&lt;br /&gt;
     if (isRed(h.right.left)&lt;br /&gt;
         h.right = rotateRight(h.right);&lt;br /&gt;
         h = rotateLeft(h);&lt;br /&gt;
         colorFlip(h);&lt;br /&gt;
 '''return''' h;   &lt;br /&gt;
&lt;br /&gt;
 '''Node''' deleteMax(h : '''Node''')&lt;br /&gt;
     if (isRed(h.left)) &lt;br /&gt;
     //вращаем все 3-вершины вправо&lt;br /&gt;
         h = rotateRight(h);&lt;br /&gt;
     //поддерживаем инвариант (h должен быть красным)&lt;br /&gt;
     if (h.right == null)   &lt;br /&gt;
         return null;&lt;br /&gt;
     //заимствуем у брата если необходимо&lt;br /&gt;
     if (!isRed(h.right) '''&amp;amp;&amp;amp;''' !isRed(h.right.left)) &lt;br /&gt;
         h = moveRedRight(h);&lt;br /&gt;
     // опускаемся на один уровень глубже &lt;br /&gt;
     h.left = deleteMax(h.left); &lt;br /&gt;
     //исправление правых красных ссылок и 4-вершин на пути вверх&lt;br /&gt;
     '''return''' fixUp(h);&lt;br /&gt;
&lt;br /&gt;
==Удаление минимума==&lt;br /&gt;
Поддерживаем инвариант: вершина или левый ребенок вершины красный.&lt;br /&gt;
&lt;br /&gt;
Заметим, что если  левый потомок вершины и левый потомок левого потомка вершины черные, необходимо переместить красную ссылку для сохранения инварианта.&lt;br /&gt;
[[File:MoveRedLeftEasy.png.png |400px|thumb|upright|Перемещение красной ссылки. Простой случай]]&lt;br /&gt;
[[File:MoveRedLeftNoEasy.png|400px|thumb|upright|Перемещение красной ссылки. Сложный случай]]&lt;br /&gt;
===Псевдокод=== &lt;br /&gt;
 '''Node''' moveRedLeft(h : '''Node''')&lt;br /&gt;
     colorFlip(h);&lt;br /&gt;
     if (isRed(h.right.left))&lt;br /&gt;
         h.right = rotateRight(h.right);&lt;br /&gt;
         h = rotateLeft(h);&lt;br /&gt;
         colorFlip(h);&lt;br /&gt;
 '''return''' h;&lt;br /&gt;
&lt;br /&gt;
 '''void''' deleteMin()&lt;br /&gt;
     root = deleteMin(root);&lt;br /&gt;
     root.color = BLACK;&lt;br /&gt;
&lt;br /&gt;
 '''Node''' deleteMin(h : '''Node''')&lt;br /&gt;
    //удаляем узел на нижнем уровне(h должен быть красным по инварианту)&lt;br /&gt;
     if (h.left == ''null'')    &lt;br /&gt;
         '''return''' ''null'';&lt;br /&gt;
     //Если необходимо, пропушим  красную ссылку вниз&lt;br /&gt;
     '''if  !'''isRed(h.left) '''&amp;amp;&amp;amp;  !'''isRed(h.left.left)&lt;br /&gt;
          h = moveRedLeft(h);&lt;br /&gt;
     //опускаемся на уровень ниже&lt;br /&gt;
     h.left = deleteMin(h.left);&lt;br /&gt;
 '''return''' fixUp(h);&lt;br /&gt;
==Асимптотика==&lt;br /&gt;
Асимптотика методов в левосторонних красно-черных деревьях эквивалентна асимптотике [[Красно-черное дерево|левосторонних красно-черных деревьях]].&lt;br /&gt;
&lt;br /&gt;
==Источники информации==&lt;br /&gt;
* Robert Sedgewick &amp;quot;Left-leaning Red-Black Trees&amp;quot; ,Department of Computer Science, Princeton University&lt;br /&gt;
== См.также ==&lt;br /&gt;
*[[Красно-черное дерево]]&lt;br /&gt;
*[[Дерево поиска, наивная реализация]]&lt;/div&gt;</summary>
		<author><name>138.197.174.51</name></author>	</entry>

	</feed>