/** * 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() ? "[0;31mRED[0m" : "[0;32mBLACK[0m"); echo PHP_EOL; if (!$node->isLeaf() && $node->haveChild(Node::POSITION_RIGHT)) { // Show left side first $this->infixeRender($node->getChild(Node::POSITION_RIGHT), $indent . ' '); } }
/** * 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)); }