|
1 | 1 | # PHP Interval tree
|
2 |
| -Implementation of interval binary search tree. |
3 | 2 |
|
4 |
| -## Installing |
| 3 | +## Overview |
| 4 | + |
| 5 | +Package **dan-on/php-interval-tree** is an implementation of self balancing binary search tree data structure called Red-Black Tree. |
| 6 | + |
| 7 | +Based on interval tree described in "Introduction to Algorithms 3rd Edition", published by Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, and Clifford Stein. |
| 8 | + |
| 9 | +## Complexity |
| 10 | + |
| 11 | +| Operation | Best, Average, Worst | |
| 12 | +|-----------|------------------------| |
| 13 | +| Insertion | O(log(n)) | |
| 14 | +| Search | O(log(n)) | |
| 15 | +| Remove | O(log(n)) | |
| 16 | +| Space | O(n) | |
| 17 | + |
| 18 | +## Installing via Composer |
| 19 | + |
5 | 20 | ```
|
6 | 21 | composer require dan-on/php-interval-tree
|
7 | 22 | ```
|
8 | 23 |
|
9 | 24 | ## Usage
|
10 | 25 |
|
| 26 | +### Intervals |
| 27 | + |
| 28 | +There are numeric and DateTimeInterface-based interval types included. |
| 29 | + |
| 30 | +#### Numeric interval |
| 31 | + |
11 | 32 | ```php
|
12 |
| -<?php |
13 |
| -require_once 'vendor/autoload.php'; |
| 33 | +use Danon\IntervalTree\Interval\NumericInterval; |
| 34 | + |
| 35 | +// Instantiate numeric interval from array |
| 36 | +$numericInterval = NumericInterval::fromArray([1, 100]); |
14 | 37 |
|
| 38 | +// Instantiate numeric interval with constructor |
| 39 | +$numericInterval = new NumericInterval(1, 100); |
| 40 | +``` |
| 41 | + |
| 42 | +#### DateTime interval |
| 43 | +```php |
| 44 | +use Danon\IntervalTree\Interval\DateTimeInterval; |
| 45 | + |
| 46 | +// Instantiate DateTime interval from array |
| 47 | +$dateTimeInterval = DateTimeInterval::fromArray([ |
| 48 | + new DateTimeImmutable('2021-01-01 00:00:00'), |
| 49 | + new DateTimeImmutable('2021-01-02 00:00:00'), |
| 50 | +]); |
| 51 | + |
| 52 | +// Instantiate DateTime interval with constructor |
| 53 | +$dateTimeInterval = new DateTimeInterval( |
| 54 | + new DateTimeImmutable('2021-01-01 00:00:00'), |
| 55 | + new DateTimeImmutable('2021-01-02 00:00:00') |
| 56 | +); |
| 57 | +``` |
| 58 | + |
| 59 | +### Interval Tree |
| 60 | + |
| 61 | +#### insert(IntervalInterface $interval, mixed $value): void |
| 62 | +Insert new pair (interval + value) into interval tree |
| 63 | +```php |
15 | 64 | use Danon\IntervalTree\IntervalTree;
|
16 | 65 |
|
17 | 66 | $tree = new IntervalTree();
|
18 |
| -$intervals = [[6, 8], [1, 4], [2, 3], [5, 12], [1, 1], [3, 5], [5, 7]]; |
19 |
| - |
20 |
| -// Insert interval as a key and interval index as a value |
21 |
| -for ($i=0; $i < count($intervals); $i++) { |
22 |
| - $tree->insert($intervals[$i], $i); |
23 |
| -} |
| 67 | +$tree->insert(new NumericInterval(1, 10), 'val1'); |
| 68 | +$tree->insert(new NumericInterval(2, 5), 'val2'); |
| 69 | +$tree->insert(new NumericInterval(11, 12), 'val3'); |
| 70 | +``` |
24 | 71 |
|
25 |
| -// Iterate nodes which keys intersect with given interval |
26 |
| -$nodesInRange = $tree->iterateIntersections([2, 3]); |
27 |
| -$intersectedIntervalIndexes = []; |
28 |
| -foreach ($nodesInRange as $node) { |
29 |
| - $intersectedIntervalIndexes[] = $node->getValue(); |
| 72 | +#### findIntersections(IntervalInterface $interval): Iterator\<Pair> |
| 73 | +Find pairs which intervals intersect with given interval |
| 74 | +```php |
| 75 | +$intersections = $tree->findIntersections(new NumericInterval(3, 5)); |
| 76 | +foreach($intersections as $pair) { |
| 77 | + $pair->getInterval()->getLow(); // 1, 2 |
| 78 | + $pair->getInterval()->getHigh(); // 10, 5 |
| 79 | + $pair->getValue(); // 'val1', 'val2' |
30 | 80 | }
|
31 |
| -// Expected array: [1, 2, 5] |
| 81 | +``` |
| 82 | + |
| 83 | +#### hasIntersection(IntervalInterface $interval): bool |
| 84 | +Returns true if interval has at least one intersection in tree |
| 85 | +```php |
| 86 | +$tree->hasIntersection(new NumericInterval(3, 5)); // true |
| 87 | +``` |
32 | 88 |
|
33 |
| -// Check that interval has at least one intersection |
34 |
| -$tree->hasIntersection([2, 3]); |
35 |
| -// Expected value: true |
| 89 | +#### countIntersections(IntervalInterface $interval): int |
| 90 | +Count intervals that has intersections |
| 91 | +```php |
| 92 | +$tree->countIntersections(new NumericInterval(3, 5)); // 2 |
| 93 | +``` |
36 | 94 |
|
37 |
| -// Count intervals that has intersections |
38 |
| -$tree->countIntersections([2, 3]); |
39 |
| -// Expected value: 3 |
| 95 | +#### remove(IntervalInterface $interval, $value): bool |
| 96 | +Remove node from tree by interval and value |
| 97 | +```php |
| 98 | +$tree->remove(new NumericInterval(11, 12), 'val3'); // true |
| 99 | +``` |
| 100 | + |
| 101 | +#### exist(IntervalInterface $interval, $value): bool |
| 102 | +Returns true if interval and value exist in the tree |
| 103 | +```php |
| 104 | +$tree->exists(new NumericInterval(11, 12), 'val3'); // true |
| 105 | +``` |
| 106 | + |
| 107 | +#### isEmpty(): bool |
| 108 | +Returns true if tree is empty |
| 109 | +```php |
| 110 | +$tree->isEmpty(); // false |
| 111 | +``` |
| 112 | + |
| 113 | +#### getSize(): int |
| 114 | +Returns number of items stored in the interval tree |
| 115 | +```php |
| 116 | +$tree->getSize(); // 3 |
40 | 117 | ```
|
41 | 118 |
|
42 | 119 | ## Tests
|
43 | 120 |
|
44 | 121 | ```
|
45 |
| -./vendor/bin/phpunit tests |
| 122 | +./vendor/bin/phpunit |
46 | 123 | ```
|
0 commit comments