Completed
Push — master ( cf78d7...547e17 )
by Siro Díaz
01:35
created

BinaryTreeAbstract::count()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 3
rs 10
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
/**
3
 * DataStructures for PHP
4
 *
5
 * @link      https://github.com/SiroDiaz/DataStructures
6
 * @copyright Copyright (c) 2017 Siro Díaz Palazón
7
 * @license   https://github.com/SiroDiaz/DataStructures/blob/master/README.md (MIT License)
8
 */
9
namespace DataStructures\Trees;
10
11
use DataStructures\Trees\Traits\CountTrait;
12
use DataStructures\Trees\Interfaces\TreeInterface;
13
use DataStructures\Trees\Interfaces\BinaryNodeInterface;
14
15
/**
16
 * BinaryTreeAbstract
17
 * 
18
 * BinaryTreeAbstract class is an abstract class that implements
19
 * common binary trees methods.
20
 *
21
 * @author Siro Diaz Palazon <[email protected]>
22
 */
23
abstract class BinaryTreeAbstract implements TreeInterface {
24
    use CountTrait;
25
    protected $root;
26
    protected $size = 0;
27
28
    abstract public function createNode($key, $data, $parent = null, $left = null, $right = null);
29
    /**
30
     * Checks if the tree is empty.
31
     *
32
     * @return boolean true if is empty, else false.
33
     */
34
    public function empty() : bool {
35
        return $this->root === null;
36
    }
37
38
    /**
39
     * Returns the tree size.
40
     *
41
     * @return int the length
42
     */
43
    public function size() : int {
44
        return $this->size;
45
    }
46
47
    /**
48
     * Inserts data in the correct position.
49
     *
50
     * @param integer|string $key the key used to store.
51
     * @param mixed $data the data to store.
52
     * @param bool $update if false the node isn't updated
53
     *  else if the key matches is updated.
54
     */
55
    public function put($key, $data, $update = false) {
56
        $newNode = $this->createNode($key, $data);
57
        
58
        if($this->root === null) {
59
            $this->root = &$newNode;
60
            $this->size++;
61
            return;
62
        }
63
64
        $parentNode = null;
65
        $current = &$this->root;
66
        while($current !== null) {
67
            $parentNode = &$current;
68
            if($key < $current->key) {
69
                $current = &$current->left;
70 View Code Duplication
            } else if($key > $current->key) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
71
                $current = &$current->right;
72
            } else {
73
                if($update) {
74
                    $current->data = $data;
75
                }
76
                return;
77
            }
78
        }
79
80
        $newNode->parent = &$parentNode;
81
        if($key < $parentNode->key) {
82
            $parentNode->left = &$newNode;
83
        } else {
84
            $parentNode->right = &$newNode;
85
        }
86
87
        $this->size++;
88
    }
89
    
90
    /**
91
     * Creates a new node or updates it if already exists.
92
     *
93
     * @param int|string $key the key.
94
     * @param mixed $data the data to be stored. 
95
     */
96
    public function putOrUpdate($key, $data) {
97
        $this->put($key, $data, true);
98
    }
99
100
    /**
101
     * Retrieve the data stored in the tree.
102
     *
103
     * @param int|string $key the key to identify the data.
104
     * @return mixed
105
     */
106
    public function get($key){
107
        if($this->root === null) {
108
            return null;
109
        }
110
111
        $node = $this->root;
112
        while($node !== null) {
113
            if($key < $node->key) {
114
                $node = $node->left;
115
            } else if($key > $node->key) {
116
                $node = $node->right;
117
            } else {
118
                return $node->data;
119
            }
120
        }
121
122
        return null;
123
    }
124
125
    /**
126
     * Returns the root node.
127
     *
128
     * @return DataStructures\Trees\Nodes\BSTNode|null the root node.
129
     */
130
    public function getRoot(){
131
        return $this->root;
132
    }
133
134
    /**
135
     * Looks for the node with the given key.
136
     *
137
     * @param int|string $key the key used to look for.
138
     * @return bool true if was found.
139
     */
140
    public function exists($key) : bool {
141
        // $this->_exists($this->root, $key); for recursive search
0 ignored issues
show
Unused Code Comprehensibility introduced by
53% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
142
        if($this->root === null) {
143
            return false;
144
        }
145
146
        if($this->root->key === $key) {
147
            return true;
148
        } else {
149
            $node = $this->root;
150
            while($node !== null) {
151 View Code Duplication
                if($key < $node->key) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
152
                    $node = $node->left;
153
                } else if($key > $node->key) {
154
                    $node = $node->right;
155
                } else {
156
                    return true;
157
                }
158
            }
159
        }
160
161
        return false;
162
    }
163
164
    /**
165
     * Method that retrieves true if found a node with the specified key.
166
     * It's the recursive version of exists method and it's used internally
167
     * for traverse through a root node.
168
     *
169
     * @param DataStructures\Trees\Nodes\BSTNode|null $node the root node.
170
     * @param int|string $key the key used to look for.
171
     * @return bool true if exists a node with that key.
172
     */
173
    private function _exists($node, $key) : bool {
174
        if($node === null) {
175
            return false;
176
        }
177
178
        if($node->key === $key) {
179
            return true;
180
        } else if($key < $node->key) {
181
            return $this->_exists($node->left, $key);
182
        } else if($key > $node->key) {
183
            return $this->_exists($node->right, $key);
184
        }
185
    }
186
187
    public function floor($key){}
188
    public function ceil($key){}
189
190
    /**
191
     * Gets the node with the minimum key. The most left and more bottom.
192
     * 
193
     * @return DataStructures\Trees\Nodes\BSTNode|null the minum node or
194
     *  null if the tree is empty.
195
     */
196
    public function min() {
197
        if($this->root === null) {
198
            return null;
199
        }
200
201
        if($this->root->left === null) {
202
            return $this->root;
203
        }
204
205
        $current = $this->root;
206
        while($current->left !== null) {
207
            $current = $current->left;
208
        }
209
210
        return $current;
211
    }
212
213
    /**
214
     * Gets the node with the maximum key. The most right and more bottom.
215
     * 
216
     * @return DataStructures\Trees\Nodes\BSTNode|null the maximum node or
217
     *  null if the tree is empty.
218
     */
219
    public function max() {
220
        if($this->root === null) {
221
            return null;
222
        }
223
224
        if($this->root->right === null) {
225
            return $this->root;
226
        }
227
228
        $node = $this->root;
229
        while($node->right !== null) {
230
            $node = $node->right;
231
        }
232
233
        return $node;
234
    }
235
236
    /**
237
     * Returns the minimum node from a given node in position X.
238
     *
239
     * @param DataStructures\Trees\Nodes\BSTNode $node the start point.
240
     * @return DataStructures\Trees\Nodes\BSTNode|null the minimum node.
241
     */
242 View Code Duplication
    private function getMinNode(BinaryNodeInterface $node = null) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
243
        if($node === null) {
244
            return null;
245
        }
246
247
        while($node->left !== null) {
248
            $node = $node->left;
249
        }
250
251
        return $node;
252
    }
253
254
    /**
255
     * Returns the maximum node from a given node in position X.
256
     *
257
     * @param DataStructures\Trees\Nodes\BSTNode $node the start point.
258
     * @return DataStructures\Trees\Nodes\BSTNode|null the maximum node.
259
     */
260 View Code Duplication
    private function getMaxNode(BinaryNodeInterface $node = null) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
261
        if($node === null) {
262
            return null;
263
        }
264
        
265
        while($node->right !== null) {
266
            $node = $node->right;
267
        }
268
269
        return $node;
270
    }
271
    
272
    /**
273
     * Deletes the node with the minimum key and returns it. The most left and more bottom.
274
     * 
275
     * @param DataStructures\Trees\Nodes\BSTNode|null if null takes the root.
276
     * @return DataStructures\Trees\Nodes\BSTNode|null the minimum node or
277
     *  null if the tree is empty.
278
     */
279 View Code Duplication
    public function deleteMin(BinaryNodeInterface $node = null) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
280
        $node = $this->getMinNode($node ?? $this->root);
281
        if($node !== null) {
282
            $this->_delete($node);
283
        }
284
        
285
        return $node;
286
    }
287
    
288
    /**
289
     * Deletes the node with the maximum key and returns it. The most right and more bottom.
290
     * 
291
     * @param DataStructures\Trees\Nodes\BSTNode|null if null takes the root.
292
     * @return DataStructures\Trees\Nodes\BSTNode|null the maximum node or
293
     *  null if the tree is empty.
294
     */
295 View Code Duplication
    public function deleteMax(BinaryNodeInterface $node = null) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
296
        $node = $this->getMaxNode($node ?? $this->root);
297
        if($node !== null) {
298
            $this->_delete($node);
299
        }
300
301
        return $node;
302
    }
303
304
    /**
305
     * Deletes the node with the maximum key and returns it. The most right and more bottom.
306
     * 
307
     * @param DataStructures\Trees\Nodes\BSTNode|null if null takes the root.
308
     * @return DataStructures\Trees\Nodes\BSTNode|null the maximum node or
309
     *  null if the tree is empty.
310
     */
311
    public function delete($key) {
312
        $deleteNode = $this->search($key);
313
        if($deleteNode !== null) {
314
            $this->_delete($deleteNode);
315
            return $deleteNode;
316
        }
317
318
        return null;
319
    }
320
321
    /**
322
     * Deletes the selected node if is not null and returns the node
323
     * that replaces the deleted node. Also decrease the size of tree.
324
     *
325
     * @param DataStructures\Trees\Nodes\BSTNode|null The node to be deleted.
326
     * @return the node that replaces the deleted.
327
     */
328
    protected function _delete(BinaryNodeInterface &$node) {
329
        if($node !== null) {
330
            $nodeToReturn = null;
331
            if($node->left === null) {
0 ignored issues
show
Bug introduced by
Accessing left on the interface DataStructures\Trees\Int...ces\BinaryNodeInterface suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
332
                $nodeToReturn = $this->replace($node, $node->right);
0 ignored issues
show
Bug introduced by
Accessing right on the interface DataStructures\Trees\Int...ces\BinaryNodeInterface suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
Documentation introduced by
$node is of type object<DataStructures\Tr...es\BinaryNodeInterface>, but the function expects a object<DataStructures\Tr...es\Trees\Nodes\BSTNode>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
333
            } else if($node->right === null) {
0 ignored issues
show
Bug introduced by
Accessing right on the interface DataStructures\Trees\Int...ces\BinaryNodeInterface suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
334
                $nodeToReturn = $this->replace($node, $node->left);
0 ignored issues
show
Bug introduced by
Accessing left on the interface DataStructures\Trees\Int...ces\BinaryNodeInterface suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
Documentation introduced by
$node is of type object<DataStructures\Tr...es\BinaryNodeInterface>, but the function expects a object<DataStructures\Tr...es\Trees\Nodes\BSTNode>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
335
            } else {
336
                $successorNode = $this->getMinNode($node->right);
0 ignored issues
show
Bug introduced by
Accessing right on the interface DataStructures\Trees\Int...ces\BinaryNodeInterface suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
337
                if($successorNode->parent !== $node) {
338
                    $this->replace($successorNode, $successorNode->right);
339
                    $successorNode->right = &$node->right;
0 ignored issues
show
Bug introduced by
Accessing right on the interface DataStructures\Trees\Int...ces\BinaryNodeInterface suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
340
                    $successorNode->right->parent = &$successorNode;
341
                }
342
343
                $this->replace($node, $successorNode);
344
                $successorNode->left = &$node->left;
345
                $successorNode->left->parent = &$successorNode;
346
                $nodeToReturn = &$successorNode;
347
            }
348
349
            $this->size--;
350
            return $nodeToReturn;
351
        }
352
353
        return null;
354
    }
355
356
    /**
357
     * Replaces the node n to remove a new one k and links k with the parent
358
     * of n.
359
     *
360
     * @param DataStructures\Trees\Nodes\BSTNode $nodeToReplace the node to remove.
361
     * @param DataStructures\Trees\Nodes\BSTNode|null $newNode the newNode
362
     *  to link with the $nodeToReplace parent.
363
     * @return DataStructures\Trees\Nodes\BSTNode the new linked node.
364
     */
365
    protected function replace(&$nodeToReplace, &$newNode) {
366
        if($nodeToReplace->parent === null) {
367
            $this->root = &$newNode;
368
        } else if($nodeToReplace === $nodeToReplace->parent->left) {
369
            $nodeToReplace->parent->left = &$newNode;
370
        } else if($nodeToReplace === $nodeToReplace->parent->right) {
371
            $nodeToReplace->parent->right = &$newNode;
372
        }
373
374
        if($newNode !== null) {
375
            $newNode->parent = &$nodeToReplace->parent;
376
        }
377
378
        return $newNode;
379
    }
380
381
    /**
382
     * Retrieves the node with the specified key.
383
     *
384
     * @param int|string $key the key used to store.
385
     * @return DataStructures\Trees\Nodes\BSTNode|null the node or null.
386
     */
387
    public function search($key) {
388
        if($this->root === null) {
389
            return null;
390
        }
391
392
        if($this->root->key === $key) {
393
            return $this->root;
394
        } else {
395
            $node = $this->root;
396
            while($node !== null) {
397 View Code Duplication
                if($key < $node->key) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
398
                    $node = $node->left;
399
                } else if($key > $node->key) {
400
                    $node = $node->right;
401
                } else {
402
                    return $node;
403
                }
404
            }
405
        }
406
407
        return null;
408
    }
409
    
410
    /**
411
     * Returns true if is leaf the node.
412
     *
413
     * @param DataStructures\Trees\Nodes\BSTNode|null $node default to null.
414
     * @return true if is leaf the node, is not null and their subtrees has no
415
     *  pointers to successors.
416
     */
417
    public function isLeaf($node) : bool { // BinaryTreeNode
418
        return ($node !== null && $node->left === null && $node->right === null);
419
    }
420
421
    /**
422
     * Checks if a node is root. New nodes that does not point to any other node
423
     * also are called a root node.
424
     *
425
     * @param DataStructures\Trees\Nodes\BSTNode|null $node default to null.
426
     * @return true if is root the node, is not null and their subtrees has no
427
     *  pointers to successors.
428
     */
429
    public function isRoot($node) : bool {
430
        return $node !== null && $node->parent === null;
431
    }
432
433
    /**
434
     * Traverse in preorder. This is: first visit the root, then
435
     * the left subtree and finally the right subtree.
436
     *
437
     * @param Callable|null $callback the callback function to apply to each
438
     *  node.
439
     */
440
    public function preorder(Callable $callback = null) {
441
        $this->_preorder($this->root, $callback);
442
    }
443
444
    /**
445
     * Private preorder traverse method that is recursive and is called by
446
     * the public preorder method.
447
     *
448
     * @param DataStructures\Trees\Nodes\BSTNode|null $node.
0 ignored issues
show
Bug introduced by
There is no parameter named $node.. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
449
     * @param Callable|null $callback the callback function to apply to each
450
     *  node.
451
     */
452 View Code Duplication
    private function _preorder($node, Callable $callback = null) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
453
        if($node === null) {
454
            return;
455
        }
456
        if($callback !== null) {
457
            call_user_func($callback, $node);
458
        }
459
        $this->_preorder($node->left, $callback);
460
        $this->_preorder($node->right, $callback);
461
    }
462
463
    /**
464
     * Traverse in inorder. This is: first visit the left subtree,
465
     * then the root and finally the right subtree.
466
     *
467
     * @param Callable|null $callback the callback function to apply to each
468
     *  node.
469
     */
470
    public function inorder(Callable $callback = null) {
0 ignored issues
show
Unused Code introduced by
The parameter $callback is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
471
        $this->_inorder($this->root);
472
    }
473
474
    /**
475
     * Private inorder traverse method that is recursive and is called by
476
     * the public inorder method.
477
     *
478
     * @param DataStructures\Trees\Nodes\BSTNode|null $node.
0 ignored issues
show
Bug introduced by
There is no parameter named $node.. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
479
     * @param Callable|null $callback the callback function to apply to each
480
     *  node.
481
     */
482 View Code Duplication
    private function _inorder($node, Callable $callback = null) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
483
        if($node === null) {
484
            return;
485
        }
486
487
        $this->_inorder($node->left, $callback);
488
        if($callback !== null) {
489
            call_user_func($callback, $node);
490
        }
491
        $this->_inorder($node->right, $callback);
492
    }
493
494
    /**
495
     * Traverse in postorder. This is: first visit the left subtree,
496
     * then the right subtree and finally the root.
497
     *
498
     * @param Callable|null $callback the callback function to apply to each
499
     *  node.
500
     */
501
    public function postorder(Callable $callback = null) {
502
        $this->_postorder($this->root, $callback);
503
    }
504
505
    /**
506
     * Private postorder traverse method that is recursive and is called by
507
     * the public postorder method.
508
     *
509
     * @param DataStructures\Trees\Nodes\BSTNode|null $node.
0 ignored issues
show
Bug introduced by
There is no parameter named $node.. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
510
     * @param Callable|null $callback the callback function to apply to each
511
     *  node.
512
     */
513 View Code Duplication
    private function _postorder($node, Callable $callback = null) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
514
        if($node === null) {
515
            return;
516
        }
517
        $this->_postorder($node->left, $callback);
518
        $this->_postorder($node->right, $callback);
519
        if($callback !== null) {
520
            call_user_func($callback, $node);
521
        }
522
    }
523
}