Skip to content

Commit

Permalink
Update InOrder traverser.
Browse files Browse the repository at this point in the history
  • Loading branch information
drupol committed Dec 28, 2018
1 parent 58c4ae3 commit 5ee6e1c
Show file tree
Hide file tree
Showing 7 changed files with 66 additions and 11 deletions.
7 changes: 3 additions & 4 deletions spec/drupol/phptree/Exporter/GraphSpec.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
namespace spec\drupol\phptree\Exporter;

use drupol\phptree\Exporter\Graph;
use drupol\phptree\Node\Node;
use drupol\phptree\Node\ValueNode;
use drupol\phptree\Traverser\BreadthFirst;
use PhpSpec\ObjectBehavior;
Expand All @@ -20,9 +19,9 @@ public function it_is_initializable()
public function it_can_generate_a_graph()
{
$root = new ValueNode('root');
$child1 = new Node();
$child2 = new Node();
$child3 = new Node();
$child1 = new ValueNode();
$child2 = new ValueNode();
$child3 = new ValueNode();
$root
->add($child1, $child2, $child3);

Expand Down
2 changes: 1 addition & 1 deletion spec/drupol/phptree/Exporter/SimpleArraySpec.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public function it_can_export_to_an_array()

$nodes = [];
foreach (\range('A', 'J') as $value) {
$nodes[$value] = new ValueNode($value);
$nodes[$value] = new ValueNode($value, 2);
}

$tree->add(...\array_values($nodes));
Expand Down
2 changes: 1 addition & 1 deletion spec/drupol/phptree/Exporter/TextSpec.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public function it_can_export_to_text()

$nodes = [];
foreach (\range('A', 'J') as $value) {
$nodes[$value] = new ValueNode($value);
$nodes[$value] = new ValueNode($value, 2);
}

$tree->add(...\array_values($nodes));
Expand Down
2 changes: 1 addition & 1 deletion spec/drupol/phptree/Node/NodeSpec.php
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ public function it_can_get_its_depth()

$nodes = [];
foreach (\range('A', 'Z') as $v) {
$nodes[] = new \drupol\phptree\Node\ValueNode($v);
$nodes[] = new \drupol\phptree\Node\ValueNode($v, 2);
}

$tree->add(...$nodes);
Expand Down
48 changes: 47 additions & 1 deletion spec/drupol/phptree/Traverser/InOrderSpec.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public function it_is_initializable()
$this->shouldHaveType(InOrder::class);
}

public function it_can_traverse_a_tree()
public function it_can_traverse_a_tree_of_degree2()
{
$tree = new ValueNode('root', 2);

Expand All @@ -39,4 +39,50 @@ public function it_can_traverse_a_tree()
->traverse($tree)
->shouldYield(new \ArrayIterator($nodes));
}

public function it_can_traverse_a_tree_of_degree4()
{
$tree = new ValueNode('root', 4);

foreach (\range('A', 'Z') as $key => $value) {
$nodes[$value] = new ValueNode($value, 4);
}

$tree->add(...\array_values($nodes));

$nodes['root'] = $tree;
$nodes = [
$nodes['U'],
$nodes['V'],
$nodes['E'],
$nodes['W'],
$nodes['X'],
$nodes['Y'],
$nodes['F'],
$nodes['Z'],
$nodes['A'],
$nodes['G'],
$nodes['H'],
$nodes['I'],
$nodes['J'],
$nodes['B'],
$nodes['K'],
$nodes['L'],
$nodes['root'],
$nodes['M'],
$nodes['N'],
$nodes['C'],
$nodes['O'],
$nodes['P'],
$nodes['Q'],
$nodes['R'],
$nodes['D'],
$nodes['S'],
$nodes['T'],
];

$this
->traverse($tree)
->shouldYield(new \ArrayIterator($nodes));
}
}
9 changes: 8 additions & 1 deletion src/Node/NaryNode.php
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ public function capacity(): int
public function add(NodeInterface ...$nodes): NodeInterface
{
foreach ($nodes as $node) {
/** @var \drupol\phptree\Node\Node $parent */
$parent = $this->findFirstAvailableNode();
$parent->storage['children'][] = $node->setParent($parent);
}
Expand All @@ -83,8 +84,14 @@ public function getTraverser()
*/
private function findFirstAvailableNode(): NodeInterface
{
$capacity = $this->capacity();

foreach ($this->getTraverser()->traverse($this) as $node) {
if ($node->degree() >= $node->capacity()) {
if (\method_exists($node, 'capacity')) {
$capacity = $node->capacity();
}

if ($node->degree() >= $capacity) {
continue;
}

Expand Down
7 changes: 5 additions & 2 deletions src/Traverser/InOrder.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,11 @@ public function traverse(NodeInterface $node): \Traversable
*/
private function doTraverse(NodeInterface $node): \Traversable
{
foreach ($node->children() as $child) {
if ($node->lastChild() === $child) {
$countChildren = $node->degree();
$middle = \floor($countChildren/2);

foreach ($node->children() as $key => $child) {
if ((int) $key === (int) $middle) {
yield $this->index => $node;
$this->index++;
}
Expand Down

0 comments on commit 5ee6e1c

Please sign in to comment.