Шаг 159.
Основы языка Haskell. Рекурсивные типы данных. Красно-чёрные деревья, AA-деревья. Алгоритм включения узла в красно-чёрное дерево (псевдокод)

    На этом шаге мы приведем этот алгоритм, представленный псевдокодом.

    Опишем алгоритм включения узла с помощью псевдокода [1], который подразумевает, что имеются функции, позволяющие:

   /* ------------------------------------------------ */
   /* Операция включения узла с ключом x на псевдокоде */
   /* ------------------------------------------------ */
   RedBlack_Insert(T,x)
   /* x        - включаемый узел; */
   /* p(x)    - "отец" узла x;    */
   /* p(p(x)) - "дедушка" узла x; */
   /* y       - "дядя" узла x     */
   /* --------------------------- */
   {
     /* Вначале осуществим "обычное" включение в бинарное */
     /* дерево поиска и покрасим узел в красный цвет      */
     /* ------------------------------------------------- */
     Tree_Insert(T,x)
     color(x)<-RED
     /* ------------------------------------------------------- */
     /* Цикл while перемещает  "нарушителя"  свойства  красного */
     /* узла вверх по дереву без нарушения свойства чёрного узла*/
     /* ------------------------------------------------------- */
     while (x!=root(T) and color(p(x))==RED)
     /* ------------------------------------------------------- */
     /* Теперь изменим порядок и цвет узлов для удовлетворения  */
     /* "красно-чёрным" свойствам.                              */
     /* Если в красно-чёрное  дерево включается  красный узел,  */
     /* то единственное правило которое  может быть нарушено -  */
     /* свойство красного узла, причём  только  в  том случае,  */
     /* если отец узла также красный                            */
     /* ------------------------------------------------------- */
     {
       if p(x)==left(p(p(x)))
       {
         y<-right(p(p(x)))
         if color(y)==RED
         /* ---------------------------------------------------- */
         /* Если отец и дядя (другой сын деда включаемого  узла) */
         /* оба красные, тогда цвет отца и дяди меняется на чёр- */
         /* ный, а цвет деда на красный.                         */
         /* Таким образом, проблема перемещается на  два  уровня */
         /* вверх, и цикл while повторяется уже для узла-деда    */
         {
           color(p(x))<-BLACK
           color(y)<-BLACK
           color(p(p(x)))<-RED
           x<-p(p(x))
         }
         /* Если отец включаемого узла является красным, а дядя */
         /* - чёрным, то существуют два похожих подслучая       */
         else {
                if x==right(p(x))
                /* Если включаемый узел является  правым  сыном */
                /* своего отца, то сначала осуществляется левый */
                /* поворот вокруг отца и затем выполняется всё, */
                /* как в предыдущем случае                      */
                {
                  x<-p(x)
                  LeftRotate(T,x)
                }
                /* Если включаемый узел  является  левым сыном */
                /* своего отца, то цвет  отца меняется на чёр- */
                /* ный, цвет деда меняется на красный.         */
                /* Далее производится  правый  поворот  вокруг */
                /* деда, полностью устраняя нарушение и закан- */
                /* чивая алгоритм                              */
                /* ------------------------------------------- */
                color(p(x))<-BLACK
                color(p(p(x)))<-RED
                RightRotate(T,p(p(x)))
              }
       }
       /* "Зеркальное" отражение предыдущего кода */
       else {
              y<-left(p(p(x)))
              if color(y)==RED
              {
                color(p(x))<-BLACK
                color(y)<-BLACK
                color(p(p(x)))<-RED
                x<-p(p(x))
              }
              else {
                     if x==left(p(x))
                     {
                       x<-p(x)
                       RightRotate(T,x)
                     }
                     color(p(x))<-BLACK
                     color(p(p(x)))<-RED
                     LeftRotate(T,p(p(x)))
                   }
            }
     }
     color(root(T))<-BLACK
   }

(1)Кормен Т., Лейзерсон Ч., Ривест Р. Алгоритмы: построение и анализ. - М.: МЦНМО, 1999. - 960 с.

    На следующем шаге мы рассмотрим удаление узла из красно-чёрного дерева.




Предыдущий шаг Содержание Следующий шаг