Skip to content

Commit 70f48a6

Browse files
committed
Add TrieNode tree type.
1 parent 78731bb commit 70f48a6

File tree

1 file changed

+60
-0
lines changed

1 file changed

+60
-0
lines changed

src/Node/TrieNode.php

+60
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
<?php
2+
3+
declare(strict_types = 1);
4+
5+
namespace drupol\phptree\Node;
6+
7+
/**
8+
* Class TrieNode
9+
*/
10+
class TrieNode extends KeyValueNode
11+
{
12+
/**
13+
* {@inheritdoc}
14+
*/
15+
public function add(NodeInterface ...$nodes): NodeInterface
16+
{
17+
foreach ($nodes as $node) {
18+
$data = $node->getValue();
19+
20+
$hash = \hash('sha256', $node->getKey() . $data);
21+
22+
$node = new TrieNode($hash, \substr($data, 0, 1));
23+
$parent = $this->append($node);
24+
25+
$dataWithoutFirstLetter = \substr($data, 1);
26+
if (!empty($dataWithoutFirstLetter)) {
27+
$parent->add(new TrieNode($hash, $dataWithoutFirstLetter));
28+
} else {
29+
$nodes = [$node->getValue()];
30+
foreach ($node->getAncestors() as $ancestor) {
31+
$nodes[] = $ancestor->getValue();
32+
}
33+
\array_pop($nodes);
34+
$node->append(new TrieNode($hash, \strrev(\implode('', $nodes))));
35+
}
36+
}
37+
38+
return $this;
39+
}
40+
41+
/**
42+
* @param \drupol\phptree\Node\ValueNodeInterface $node
43+
*
44+
* @return \drupol\phptree\Node\NodeInterface|\drupol\phptree\Node\ValueNodeInterface
45+
*/
46+
private function append(ValueNodeInterface $node)
47+
{
48+
/** @var \drupol\phptree\Node\ValueNodeInterface $child */
49+
foreach ($this->children() as $child) {
50+
/** @var \drupol\phptree\Node\ValueNodeInterface $node */
51+
if ($node->getValue() === $child->getValue()) {
52+
return $child;
53+
}
54+
}
55+
56+
parent::add($node);
57+
58+
return $node;
59+
}
60+
}

0 commit comments

Comments
 (0)