Skip to content

Commit eb4efa8

Browse files
committed
Add an Auto Balanced Node.
1 parent eb0e182 commit eb4efa8

File tree

2 files changed

+118
-0
lines changed

2 files changed

+118
-0
lines changed
+69
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
<?php
2+
3+
declare(strict_types = 1);
4+
5+
namespace spec\drupol\phptree\Node;
6+
7+
use drupol\phptree\Node\ABNode;
8+
9+
class ABNodeSpec extends NodeObjectBehavior
10+
{
11+
public function it_balance_a_tree()
12+
{
13+
$this->beConstructedWith(1);
14+
15+
$data = \range(0, 40);
16+
17+
$nodes = [];
18+
foreach ($data as $key => $value) {
19+
$nodes[$key] = new ABNode(2);
20+
}
21+
22+
$this
23+
->add(...$nodes);
24+
25+
$this->offsetGet(0)->count()->shouldReturn(40);
26+
$this
27+
->offsetGet(0)
28+
->offsetGet(0)
29+
->count()
30+
->shouldReturn(19);
31+
$this
32+
->offsetGet(0)
33+
->offsetGet(1)
34+
->count()
35+
->shouldReturn(19);
36+
37+
$this
38+
->add(new ABNode(2));
39+
40+
$this
41+
->offsetGet(0)
42+
->offsetGet(0)
43+
->count()
44+
->shouldReturn(19);
45+
$this
46+
->offsetGet(0)
47+
->offsetGet(1)
48+
->count()
49+
->shouldReturn(20);
50+
51+
$this
52+
->add(new ABNode(2));
53+
54+
$this
55+
->offsetGet(0)
56+
->offsetGet(0)
57+
->count()
58+
->shouldReturn(20);
59+
$this
60+
->offsetGet(0)
61+
->offsetGet(1)
62+
->count()
63+
->shouldReturn(20);
64+
}
65+
public function it_is_initializable()
66+
{
67+
$this->shouldHaveType(ABNode::class);
68+
}
69+
}

src/Node/ABNode.php

+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<?php
2+
3+
declare(strict_types = 1);
4+
5+
namespace drupol\phptree\Node;
6+
7+
/**
8+
* Class ABNode.
9+
*
10+
* An auto-balanced node.
11+
*/
12+
class ABNode extends NaryNode
13+
{
14+
/**
15+
* {@inheritdoc}
16+
*/
17+
public function add(NodeInterface ...$nodes): NodeInterface
18+
{
19+
foreach ($nodes as $node) {
20+
if (0 === $this->count()) {
21+
parent::add($node);
22+
23+
continue;
24+
}
25+
26+
$count = [];
27+
28+
foreach ($this->children() as $child) {
29+
$count[$child->count()] = $child;
30+
}
31+
32+
$keys = \array_keys($count);
33+
$keys[] = 0;
34+
35+
if (\min($keys) === \max($keys)) {
36+
parent::add($node);
37+
38+
continue;
39+
}
40+
41+
\ksort($count);
42+
43+
$child = \array_shift($count);
44+
$child->add($node);
45+
}
46+
47+
return $this;
48+
}
49+
}

0 commit comments

Comments
 (0)