/** * 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 . ' '); } }
/** * Remove the node from the tree. * The removed node will be orphan (no child nor parent). * * @param Node $node * @return $this */ public function remove(Node $node) { if (!$node->haveChild(Node::POSITION_LEFT) || !$node->haveChild(Node::POSITION_RIGHT)) { $tmp = $node; } else { $tmp = $this->findRelative($node, null === $node->getPosition() ? Node::POSITION_RIGHT : $node->getPosition()); } $alt = $tmp->getChild(Node::POSITION_LEFT) ?: $tmp->getChild(Node::POSITION_RIGHT); if (null === $alt) { $alt = $tmp; } $alt->setParent($tmp->getParent()); if (null === $node->getParent()) { $this->root = $alt; } elseif (null !== $tmp->getParent()) { $tmp->getParent()->setChild($tmp->getPosition(), $alt); } if ($tmp !== $node) { if ($tmp !== $alt && Node::COLOR_BLACK === $tmp->getColor()) { $this->deleteSort($alt); } if (null !== $tmp->getParent()) { $tmp->getParent()->setChild($tmp->getPosition(), $tmp->getChild($tmp->getPosition())); } $tmp->setChild(Node::POSITION_LEFT, $node->getChild(Node::POSITION_LEFT))->setChild(Node::POSITION_RIGHT, $node->getChild(Node::POSITION_RIGHT))->setParent($node->getParent())->setColor($node->getColor()); if ($node->haveChild(Node::POSITION_LEFT)) { $node->getChild(Node::POSITION_LEFT)->setParent($tmp); } if ($node->haveChild(Node::POSITION_RIGHT)) { $node->getChild(Node::POSITION_RIGHT)->setParent($tmp); } if (null !== $node->getParent()) { $node->getParent()->setChild($node->getPosition(), $tmp); } } else { if (Node::COLOR_BLACK === $node->getColor()) { $this->deleteSort($node); } } // Make original node orphan if (null !== $node->getParent() && $node === $node->getParent()->getChild($node->getPosition())) { $node->getParent()->setChild($node->getPosition(), null); } $node->setPosition(null)->setParent(null)->setChild(Node::POSITION_LEFT, null)->setChild(Node::POSITION_RIGHT, null); return $this; }