예제 #1
0
 /**
  * Do rotations on related places on deletion
  *
  * @param Node $node
  * @return $this
  */
 protected function deleteSort(Node $node)
 {
     // If is root or black, go back
     if (Node::COLOR_BLACK !== $node->getColor() || null === $node->getParent()) {
         return $this;
     }
     $direction = $node->getPosition();
     $tmp = $node->getParent()->getChild(-$direction);
     if (null !== $tmp) {
         if (Node::COLOR_RED === $tmp->getColor()) {
             $tmp->setColor(Node::COLOR_BLACK);
             $node->getParent()->setColor(Node::COLOR_RED);
             $this->rotate($node->getParent(), $direction);
             $tmp = $node->getParent()->getChild(-$direction);
         }
         if ($tmp->haveChild(Node::POSITION_LEFT) && $tmp->getChild(Node::POSITION_LEFT)->getColor() === Node::COLOR_BLACK && $tmp->haveChild(Node::POSITION_RIGHT) && $tmp->getChild(Node::POSITION_RIGHT)->getColor() === Node::COLOR_BLACK) {
             $tmp->setColor(Node::COLOR_RED);
             return $this->deleteSort($node->getParent());
         } else {
             if ($tmp->haveChild(-$direction) && $tmp->getChild(-$direction)->getColor() === Node::COLOR_BLACK) {
                 if ($tmp->haveChild($direction)) {
                     $tmp->getChild($direction)->setColor(Node::COLOR_BLACK);
                 }
                 $tmp->setColor(Node::COLOR_RED);
                 $this->rotate($tmp, -$direction);
                 $tmp = $node->getParent()->getChild(-$direction);
             }
             $tmp->setColor($node->getParent()->getColor());
             $node->getParent()->setColor(Node::COLOR_BLACK);
             if ($tmp->getChild(-$direction)) {
                 $tmp->getChild(-$direction)->setColor(Node::COLOR_BLACK);
             }
             $this->rotate($node->getParent(), $direction);
             $node = $this->root;
         }
     }
     return $this->deleteSort($node->setColor(Node::COLOR_BLACK));
 }
예제 #2
0
 /**
  * Simple recursive visualisation.
  * The first node should be the root.
  * Colors are for linux console, sorry windows guys :p
  *
  * @param Node $node
  * @param string $indent
  * @return string The max indentation
  */
 protected function infixeRender(Node $node, $indent = '')
 {
     if (!$node->isLeaf() && $node->haveChild(Node::POSITION_LEFT)) {
         // Show left side first
         $this->infixeRender($node->getChild(Node::POSITION_LEFT), $indent . '  ');
     }
     echo sprintf('%s%s#%d', $indent, $node->getPosition() == 0 ? '-' : ($node->getPosition() > 0 ? '\\' : '/'), $node->getId());
     echo ' L#' . ($node->haveChild(Node::POSITION_LEFT) ? $node->getChild(Node::POSITION_LEFT)->getId() : '-');
     echo ' R#' . ($node->haveChild(Node::POSITION_RIGHT) ? $node->getChild(Node::POSITION_RIGHT)->getId() : '-');
     echo ' P#' . (null !== $node->getParent() ? $node->getParent()->getId() : '-');
     echo ' C:' . (Node::COLOR_RED === $node->getColor() ? "RED" : "BLACK");
     echo PHP_EOL;
     if (!$node->isLeaf() && $node->haveChild(Node::POSITION_RIGHT)) {
         // Show left side first
         $this->infixeRender($node->getChild(Node::POSITION_RIGHT), $indent . '  ');
     }
 }