Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 50 additions & 13 deletions src/helper/Node.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,62 +7,99 @@ class Node
private Node|null $parent;
private Node|null $right;
private Node|null $left;
private Int $value;
private float|int $value;

public function __construct($value, Node $node = null)
/**
* @param float|int $value
* @param Node|null $node
*/
public function __construct(float|int $value, Node $node = null)
{
$this->parent = $node;
$this->value = $value;
$this->left = null;
$this->right = null;
}

/**
* @return Node|null the parent of the node
*/
public function parent(): Node|null
{
return $this->parent;
}

public function value(): Int
/**
* @return float|int
*/
public function value(): float|int
{
return $this->value;
}

/**
* @return Node|null the left child
*/
public function left(): Node|null
{
return $this->left;
}

/**
* @return Node|null the right child
*/
public function right(): Node|null
{
return $this->right;
}

public function setLeft($value): Node
/**
* set the parent to provided Node
*
* @param ?Node $node
* @return Node
*/
public function setParent(?Node $node): Node
{
$newNode = new Node($value, $this);

return $this->left = $newNode;
return $this->parent = $node;
}

public function setRight($value): Node
/**
* set the left child to provided Node
*
* @param ?Node $node
* @return Node
*/
public function setLeft(?Node $node): Node
{
$newNode = new Node($value, $this);
return $this->left = $node;
}

return $this->right = $newNode;
/**
* set the right child to provided Node
*
* @param ?Node $node
* @return Node
*/
public function setRight(?Node $node): Node
{
return $this->right = $node;
}

/**
* travel the tree from the current node and return array representation
*
* @return array<int, float>
*/
public function flatten(): array
{
$left = [];
$right = [];
if ($this->left() != null) {
$left = $this->left()->flatten();
if ($this->left != null) {
$left = $this->left->flatten();
}
if ($this->right != null) {
$right = $this->right()->flatten();
$right = $this->right->flatten();
}

return array_merge($left, [$this->value], $right);
Expand Down
83 changes: 78 additions & 5 deletions src/helper/Tree.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,28 @@ class Tree
{
private ?Node $root;

public function __construct($value)
/**
* @param float|int $value
*/
public function __construct(float|int $value)
{
$this->root = new Node($value);
}

public function root(): Node
/**
* @return Node|null
*/
public function root(): ?Node
{
return $this->root;
}

public function put($value, Node $node = null): void
/**
* @param float|int $value
* @param Node|null $node
* @return void
*/
public function put(float|int $value, Node $node = null): void
{
if ($node == null) {
$this->put($value, $this->root);
Expand All @@ -25,16 +36,78 @@ public function put($value, Node $node = null): void
}
if ($node->value() < $value) {
if ($node->right() == null) {
$node->setRight($value);
$newNode = new Node($value, $node);
$node->setRight($newNode);
} else {
$this->put($value, $node->right());
}
} else {
if ($node->left() == null) {
$node->setLeft($value);
$newNode = new Node($value, $node);
$node->setLeft($newNode);
} else {
$this->put($value, $node->left());
}
}
}

/**
* search for node with provided value and remove it from tree
*
* @param float|int $value to search and remove
* @return float|int|null the value found or null on not existing
*/
public function pull(float|int $value): float|int|null
{
$pointer = $this->root;
while ($pointer && $pointer->value() != $value) {
if ($pointer->value() < $value) {
$pointer = $pointer->right();
} elseif ($value < $pointer->value()) {
$pointer = $pointer->left();
}
}
if (!$pointer) {
return null;
}
if (!$pointer->parent()) {
$this->root = null;
return $value;
}
if (!$pointer->left() && !$pointer->right()) {
if ($pointer->parent()->left() === $pointer) {
$pointer->parent()->setLeft(null);
} else {
$pointer->parent()->setRight(null);
}
return $value;
}
if(!$pointer->right()) {
$pointer->left()->setParent($pointer->parent());
if ($pointer->parent()->left() === $pointer) {
$pointer->parent()->setLeft($pointer->left());
} else {
$pointer->parent()->setRight($pointer->left());
}
return $value;
}
$inorderSuccessor = $pointer->right();
while ($inorderSuccessor->left()) {
$inorderSuccessor = $inorderSuccessor->left();
}
if ($inorderSuccessor->parent()->left() === $inorderSuccessor) {
$inorderSuccessor->parent()->setLeft($inorderSuccessor->right());
} else {
$inorderSuccessor->parent()->setRight($inorderSuccessor->right());
}
if ($pointer->parent()->left() === $pointer) {
$pointer->parent()->setLeft($inorderSuccessor);
} else {
$pointer->parent()->setRight($inorderSuccessor);
}
$inorderSuccessor->setRight($pointer->right());
$inorderSuccessor->setLeft($pointer->left());
$pointer->left()->setParent($inorderSuccessor);
return $value;
}
}
Loading