Skip to content

Commit 06a0f8a

Browse files
committed
refactoring
1 parent 54dca08 commit 06a0f8a

File tree

4 files changed

+54
-90
lines changed

4 files changed

+54
-90
lines changed

README.md

+24-21
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# PHP Interval tree
2-
Is an implementation of interval binary search tree according to Thomas H. Cormen book "Introduction to Algorithms".
2+
Implementation of interval binary search tree.
33

44
## Usage
55

@@ -10,27 +10,30 @@ require_once 'vendor/autoload.php';
1010
use Danon\IntervalTree\IntervalTree;
1111

1212
$tree = new IntervalTree();
13-
$intervals = [[6,8],[1,4],[2,3],[5,12],[1,1],[3,5],[5,7]];
14-
15-
// Insert interval as a key and string "val0", "val1" etc. as a value
13+
$intervals = [[6, 8], [1, 4], [2, 3], [5, 12], [1, 1], [3, 5], [5, 7]];
14+
15+
// Insert interval as a key and interval index as a value
1616
for ($i=0; $i < count($intervals); $i++) {
17-
$tree->insert($intervals[$i], "val" . $i);
17+
$tree->insert($intervals[$i], $i);
18+
}
19+
20+
// Iterate nodes which keys intersect with given interval
21+
$nodesInRange = $tree->iterateIntersections([2, 3]);
22+
$intersectedIntervalIndexes = [];
23+
foreach ($nodesInRange as $node) {
24+
$intersectedIntervalIndexes[] = $node->getValue();
1825
}
26+
// Expected array: [1, 2, 5]
27+
28+
// Check that interval has at least one intersection
29+
$tree->hasIntersection([2, 3]);
30+
// Expected value: true
31+
32+
// Count intervals that has intersections
33+
$tree->countIntersections([2, 3]);
34+
// Expected value: 3
1935

2036
// Get array of keys sorted in ascendant order
21-
$sorted_intervals = $tree->getKeys(); // expected array [[1,1],[1,4],[5,7],[5,12],[6,8]]
22-
23-
// Search items which keys intersect with given interval, and return array of values
24-
$valuesInRange = $tree->search([2,3], function($value, $key) {
25-
return $value;
26-
});
27-
28-
print_r($valuesInRange);
29-
30-
// Array
31-
// (
32-
// [0] => val1
33-
// [1] => val2
34-
// [2] => val5
35-
// )
36-
```
37+
$sortedIntervals = $tree->getKeys();
38+
// Expected array: [[1, 1], [1, 4], [2, 3], [3, 5], [5, 7], [5, 12], [6, 8]]
39+
```

examples/index.php

-50
This file was deleted.

src/IntervalTree.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ public function iterateIntersections(array $interval): iterable
101101
* @param array $interval
102102
* @return boolean
103103
*/
104-
public function hasIntersect(array $interval): bool
104+
public function hasIntersection(array $interval): bool
105105
{
106106
$nodesIterator = $this->iterateIntersections($interval);
107107
return $nodesIterator->current() !== null;
@@ -126,7 +126,7 @@ public function countIntersections($interval): int
126126
* @param mixed $value - value representing any object (optional)
127127
* @return Node - returns reference to inserted node
128128
*/
129-
public function insert(array $key, mixed $value = null)
129+
public function insert(array $key, $value = null)
130130
{
131131
if ($key === null) {
132132
return;

src/Node.php

+28-17
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
<?php
22
namespace Danon\IntervalTree;
33

4-
class Node {
4+
class Node
5+
{
56

67
public const COLOR_RED = 0;
78
public const COLOR_BLACK = 1;
@@ -30,14 +31,15 @@ class Node {
3031

3132
public $max;
3233

33-
public function __construct($key = null, $value = null, $left = null, $right = null, $parent = null, $color = self::COLOR_BLACK) {
34+
public function __construct($key = null, $value = null, $left = null, $right = null, $parent = null, $color = self::COLOR_BLACK)
35+
{
3436

3537
$this->left = $left;
3638
$this->right = $right;
3739
$this->parent = $parent;
3840
$this->color = $color;
3941

40-
$this->item = (object)compact('key', 'value'); // key is supposed to be instance of Interval
42+
$this->item = (object) compact('key', 'value'); // key is supposed to be instance of Interval
4143

4244
/* If not, this should by an array of two numbers */
4345
if ($key && is_array($key) && count($key) === 2) {
@@ -47,64 +49,73 @@ public function __construct($key = null, $value = null, $left = null, $right = n
4749
$this->max = $this->item->key ? clone $this->item->key : null;
4850
}
4951

50-
public function getValue() {
52+
public function getValue()
53+
{
5154
return $this->item->value;
5255
}
5356

54-
55-
public function getKey() {
57+
public function getKey()
58+
{
5659
return $this->item->key;
5760
}
5861

59-
public function isNil() {
62+
public function isNil()
63+
{
6064
return ($this->item->key === null && $this->item->value === null &&
6165
$this->left === null && $this->right === null && $this->color === Node::COLOR_BLACK);
6266
}
6367

64-
public function lessThan($otherNode) {
68+
public function lessThan($otherNode)
69+
{
6570
return $this->item->key->lessThan($otherNode->item->key);
6671
}
6772

68-
public function equalTo($otherNode) {
73+
public function equalTo($otherNode)
74+
{
6975
$valueEqual = true;
7076
if ($this->item->value && $otherNode->item->value) {
7177
$valueEqual = $this->item->value ? $this->item->value->equalTo($otherNode->item->value) :
72-
$this->item->value == $otherNode->item->value;
78+
$this->item->value == $otherNode->item->value;
7379
}
7480
return $this->item->key->equalTo($otherNode->item->key) && $valueEqual;
7581
}
7682

77-
public function intersect($otherNode) {
83+
public function intersect($otherNode)
84+
{
7885
return $this->item->key->intersect($otherNode->item->key);
7986
}
8087

81-
public function copyData($otherNode) {
88+
public function copyData($otherNode)
89+
{
8290
$this->item->key = clone $otherNode->item->key;
8391
$this->item->value = $otherNode->item->value;
8492
}
8593

86-
public function updateMax() {
94+
public function updateMax()
95+
{
8796
// use key (Interval) max property instead of key.high
8897
$this->max = $this->item->key ? $this->item->key->getMax() : null;
8998
if ($this->right && $this->right->max) {
90-
$this->max = Interval::comparableMax($this->max, $this->right->max); // static method
99+
$this->max = Interval::comparableMax($this->max, $this->right->max); // static method
91100
}
92101
if ($this->left && $this->left->max) {
93102
$this->max = Interval::comparableMax($this->max, $this->left->max);
94103
}
95104
}
96105

97106
// Other_node does not intersect any node of left subtree, if this.left.max < other_node.item.key.low
98-
public function notIntersectLeftSubtree($searchNode) {
107+
public function notIntersectLeftSubtree($searchNode)
108+
{
99109
//const comparable_less_than = this.item.key.constructor.comparable_less_than; // static method
100110
$high = $this->left->max->high !== null ? $this->left->max->high : $this->left->max;
101111
return Interval::comparableLessThan($high, $searchNode->item->key->low);
102112
}
103113

104114
// Other_node does not intersect right subtree if other_node.item.key.high < this.right.key.low
105-
public function notIntersectRightSubtree($searchNode) {
115+
public function notIntersectRightSubtree($searchNode)
116+
{
106117
//const comparable_less_than = this.item.key.constructor.comparable_less_than; // static method
107118
$low = $this->right->max->low !== null ? $this->right->max->low : $this->right->item->key->low;
108119
return Interval::comparableLessThan($searchNode->item->key->high, $low);
109120
}
110-
}
121+
}

0 commit comments

Comments
 (0)