Completed
Push — master ( f1605c...0f0c8b )
by Siro Díaz
02:06
created

BinaryTreeAbstract::put()   C

Complexity

Conditions 7
Paths 9

Size

Total Lines 34
Code Lines 24

Duplication

Lines 8
Ratio 23.53 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
dl 8
loc 34
rs 6.7272
c 1
b 0
f 0
cc 7
eloc 24
nc 9
nop 3
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\Interfaces\TreeInterface;
12
use DataStructures\Trees\Interfaces\BinaryNodeInterface;
13
14
/**
15
 * BinaryTreeAbstract
16
 * 
17
 * BinaryTreeAbstract class is an abstract class that implements
18
 * common binary trees methods.
19
 *
20
 * @author Siro Diaz Palazon <[email protected]>
21
 */
22
abstract class BinaryTreeAbstract implements TreeInterface {
23
    protected $root;
24
    protected $size;
25
26
    public abstract function createNode($key, $data, $parent = null, $left = null, $right = null);
0 ignored issues
show
Coding Style introduced by
The abstract declaration must precede the visibility declaration
Loading history...
27
    /**
28
     * Checks if the tree is empty.
29
     *
30
     * @return boolean true if is empty, else false.
31
     */
32
    public function empty() {
33
        return $this->root === null;
34
    }
35
36
    /**
37
     * Returns the tree size.
38
     *
39
     * @return int the length
40
     */
41
    public function size() {
42
        return $this->size;
43
    }
44
45
    /**
46
     * Inserts data in the correct position.
47
     *
48
     * @param integer|string $key the key used to store.
49
     * @param mixed $data the data to store.
50
     * @param bool $update if false the node isn't updated
51
     *  else if the key matches is updated.
52
     */
53
    public function put($key, $data, $update = false) {
54
        $newNode = $this->createNode($key, $data);
55
        
56
        if($this->root === null) {
57
            $this->root = &$newNode;
58
            $this->size++;
59
            return;
60
        }
61
62
        $parentNode = null;
63
        $current = &$this->root;
64
        while($current !== null) {
65
            $parentNode = &$current;
66
            if($key < $current->key) {
67
                $current = &$current->left;
68 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...
69
                $current = &$current->right;
70
            } else {
71
                if($update) {
72
                    $current->data = $data;
73
                }
74
                return;
75
            }
76
        }
77
78
        $newNode->parent = &$parentNode;
79
        if($key < $parentNode->key) {
80
            $parentNode->left = &$newNode;
81
        } else {
82
            $parentNode->right = &$newNode;
83
        }
84
85
        $this->size++;
86
    }
87
    
88
    /**
89
     * Creates a new node or updates it if already exists.
90
     *
91
     * @param int|string $key the key.
92
     * @param mixed $data the data to be stored. 
93
     */
94
    public function putOrUpdate($key, $data) {
95
        $this->put($key, $data, true);
96
    }
97
98
    /**
99
     * Retrieve the data stored in the tree.
100
     *
101
     * @param int|string $key the key to identify the data.
102
     * @return mixed
103
     */
104
    public function get($key){
105
        if($this->root === null) {
106
            return null;
107
        }
108
109
        $node = $this->root;
110
        while($node !== null) {
111
            if($key < $node->key) {
112
                $node = $node->left;
113
            } else if($key > $node->key) {
114
                $node = $node->right;
115
            } else {
116
                return $node->data;
117
            }
118
        }
119
120
        return null;
121
    }
122
123
    /**
124
     * Returns the root node.
125
     *
126
     * @return DataStructures\Trees\Nodes\BSTNode|null the root node.
127
     */
128
    public function getRoot(){
129
        return $this->root;
130
    }
131
132
    /**
133
     * Looks for the node with the given key.
134
     *
135
     * @param int|string $key the key used to look for.
136
     * @return bool true if was found.
137
     */
138
    public function exists($key){
139
        // $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...
140
        if($this->root === null) {
141
            return false;
142
        }
143
144
        if($this->root->key === $key) {
145
            return true;
146
        } else {
147
            $node = $this->root;
148
            while($node !== null) {
149 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...
150
                    $node = $node->left;
151
                } else if($key > $node->key) {
152
                    $node = $node->right;
153
                } else {
154
                    return true;
155
                }
156
            }
157
        }
158
159
        return false;
160
    }
161
162
    /**
163
     * Method that retrieves true if found a node with the specified key.
164
     * It's the recursive version of exists method and it's used internally
165
     * for traverse through a root node.
166
     *
167
     * @param DataStructures\Trees\Nodes\BSTNode|null $node the root node.
168
     * @param int|string $key the key used to look for.
169
     * @return bool true if exists a node with that key.
170
     */
171
    private function _exists($node, $key) : bool {
172
        if($node === null) {
173
            return false;
174
        }
175
176
        if($node->key === $key) {
177
            return true;
178
        } else if($key < $node->key) {
179
            return $this->_exists($node->left, $key);
180
        } else if($key > $node->key) {
181
            return $this->_exists($node->right, $key);
182
        }
183
    }
184
185
    public function floor($key){}
186
    public function ceil($key){}
187
188
    /**
189
     * Gets the node with the minimum key. The most left and more bottom.
190
     * 
191
     * @return DataStructures\Trees\Nodes\BSTNode|null the minum node or
192
     *  null if the tree is empty.
193
     */
194
    public function min() {
195
        if($this->root === null) {
196
            return null;
197
        }
198
199
        if($this->root->left === null) {
200
            return $this->root;
201
        }
202
203
        $current = $this->root;
204
        while($current->left !== null) {
205
            $current = $current->left;
206
        }
207
208
        return $current;
209
    }
210
211
    /**
212
     * Gets the node with the maximum key. The most right and more bottom.
213
     * 
214
     * @return DataStructures\Trees\Nodes\BSTNode|null the maximum node or
215
     *  null if the tree is empty.
216
     */
217
    public function max() {
218
        if($this->root === null) {
219
            return null;
220
        }
221
222
        if($this->root->right === null) {
223
            return $this->root;
224
        }
225
226
        $node = $this->root;
227
        while($node->right !== null) {
228
            $node = $node->right;
229
        }
230
231
        return $node;
232
    }
233
234
    /**
235
     * Returns the minimum node from a given node in position X.
236
     *
237
     * @param DataStructures\Trees\Nodes\BSTNode $node the start point.
238
     * @return DataStructures\Trees\Nodes\BSTNode|null the minimum node.
239
     */
240 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...
241
        if($node === null) {
242
            return null;
243
        }
244
245
        while($node->left !== null) {
246
            $node = $node->left;
247
        }
248
249
        return $node;
250
    }
251
252
    /**
253
     * Returns the maximum node from a given node in position X.
254
     *
255
     * @param DataStructures\Trees\Nodes\BSTNode $node the start point.
256
     * @return DataStructures\Trees\Nodes\BSTNode|null the maximum node.
257
     */
258 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...
259
        if($node === null) {
260
            return null;
261
        }
262
        
263
        while($node->right !== null) {
264
            $node = $node->right;
265
        }
266
267
        return $node;
268
    }
269
    
270
    /**
271
     * Deletes the node with the minimum key and returns it. The most left and more bottom.
272
     * 
273
     * @param DataStructures\Trees\Nodes\BSTNode|null if null takes the root.
274
     * @return DataStructures\Trees\Nodes\BSTNode|null the minimum node or
275
     *  null if the tree is empty.
276
     */
277 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...
278
        $node = $this->getMinNode($node ?? $this->root);
279
        if($node !== null) {
280
            $this->_delete($node);
281
        }
282
        
283
        return $node;
284
    }
285
    
286
    /**
287
     * Deletes the node with the maximum key and returns it. The most right and more bottom.
288
     * 
289
     * @param DataStructures\Trees\Nodes\BSTNode|null if null takes the root.
290
     * @return DataStructures\Trees\Nodes\BSTNode|null the maximum node or
291
     *  null if the tree is empty.
292
     */
293 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...
294
        $node = $this->getMaxNode($node ?? $this->root);
295
        if($node !== null) {
296
            $this->_delete($node);
297
        }
298
299
        return $node;
300
    }
301
302
    /**
303
     * Deletes the node with the maximum key and returns it. The most right and more bottom.
304
     * 
305
     * @param DataStructures\Trees\Nodes\BSTNode|null if null takes the root.
306
     * @return DataStructures\Trees\Nodes\BSTNode|null the maximum node or
307
     *  null if the tree is empty.
308
     */
309
    public function delete($key) {
310
        $deleteNode = $this->search($key);
311
        if($deleteNode !== null) {
312
            $this->_delete($deleteNode);
313
            return $deleteNode;
314
        }
315
316
        return null;
317
    }
318
319
    /**
320
     * Deletes the selected node if is not null and returns the node
321
     * that replaces the deleted node. Also decrease the size of tree.
322
     *
323
     * @param DataStructures\Trees\Nodes\BSTNode|null The node to be deleted.
324
     * @return the node that replaces the deleted.
325
     */
326
    protected function _delete(BinaryNodeInterface &$node) {
327
        if($node !== null) {
328
            $nodeToReturn = null;
329
            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...
330
                $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...
331
            } 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...
332
                $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...
333
            } else {
334
                $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...
335
                if($successorNode->parent !== $node) {
336
                    $this->replace($successorNode, $successorNode->right);
337
                    $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...
338
                    $successorNode->right->parent = &$successorNode;
339
                }
340
341
                $this->replace($node, $successorNode);
342
                $successorNode->left = &$node->left;
343
                $successorNode->left->parent = &$successorNode;
344
                $nodeToReturn = &$successorNode;
345
            }
346
347
            $this->size--;
348
            return $nodeToReturn;
349
        }
350
351
        return null;
352
    }
353
354
    /**
355
     * Replaces the node n to remove a new one k and links k with the parent
356
     * of n.
357
     *
358
     * @param DataStructures\Trees\Nodes\BSTNode $nodeToReplace the node to remove.
359
     * @param DataStructures\Trees\Nodes\BSTNode|null $newNode the newNode
360
     *  to link with the $nodeToReplace parent.
361
     * @return DataStructures\Trees\Nodes\BSTNode the new linked node.
362
     */
363
    protected function replace(&$nodeToReplace, &$newNode) {
364
        if($nodeToReplace->parent === null) {
365
            $this->root = &$newNode;
366
        } else if($nodeToReplace === $nodeToReplace->parent->left) {
367
            $nodeToReplace->parent->left = &$newNode;
368
        } else if($nodeToReplace === $nodeToReplace->parent->right) {
369
            $nodeToReplace->parent->right = &$newNode;
370
        }
371
372
        if($newNode !== null) {
373
            $newNode->parent = &$nodeToReplace->parent;
374
        }
375
376
        return $newNode;
377
    }
378
379
    /**
380
     * Retrieves the node with the specified key.
381
     *
382
     * @param int|string $key the key used to store.
383
     * @return DataStructures\Trees\Nodes\BSTNode|null the node or null.
384
     */
385
    public function search($key) {
386
        if($this->root === null) {
387
            return null;
388
        }
389
390
        if($this->root->key === $key) {
391
            return $this->root;
392
        } else {
393
            $node = $this->root;
394
            while($node !== null) {
395 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...
396
                    $node = $node->left;
397
                } else if($key > $node->key) {
398
                    $node = $node->right;
399
                } else {
400
                    return $node;
401
                }
402
            }
403
        }
404
405
        return null;
406
    }
407
    
408
    /**
409
     * Returns true if is leaf the node.
410
     *
411
     * @param DataStructures\Trees\Nodes\BSTNode|null $node default to null.
412
     * @return true if is leaf the node, is not null and their subtrees has no
413
     *  pointers to successors.
414
     */
415
    public function isLeaf($node) { // BinaryTreeNode
416
        return ($node !== null && $node->left === null && $node->right === null);
417
    }
418
419
    /**
420
     * Checks if a node is root. New nodes that does not point to any other node
421
     * also are called a root node.
422
     *
423
     * @param DataStructures\Trees\Nodes\BSTNode|null $node default to null.
424
     * @return true if is root the node, is not null and their subtrees has no
425
     *  pointers to successors.
426
     */
427
    public function isRoot($node) {
428
        return $node !== null && $node->parent === null;
429
    }
430
431
    /**
432
     * Traverse in preorder. This is: first visit the root, then
433
     * the left subtree and finally the right subtree.
434
     *
435
     * @param Callable|null $callback the callback function to apply to each
436
     *  node.
437
     */
438
    public function preorder(Callable $callback = null) {
439
        $this->_preorder($this->root, $callback);
440
    }
441
442
    /**
443
     * Private preorder traverse method that is recursive and is called by
444
     * the public preorder method.
445
     *
446
     * @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...
447
     * @param Callable|null $callback the callback function to apply to each
448
     *  node.
449
     */
450 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...
451
        if($node === null) {
452
            return;
453
        }
454
        if($callback !== null) {
455
            call_user_func($callback, $node);
456
        }
457
        $this->_preorder($node->left, $callback);
458
        $this->_preorder($node->right, $callback);
459
    }
460
461
    /**
462
     * Traverse in inorder. This is: first visit the left subtree,
463
     * then the root and finally the right subtree.
464
     *
465
     * @param Callable|null $callback the callback function to apply to each
466
     *  node.
467
     */
468
    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...
469
        $this->_inorder($this->root);
470
    }
471
472
    /**
473
     * Private inorder traverse method that is recursive and is called by
474
     * the public inorder method.
475
     *
476
     * @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...
477
     * @param Callable|null $callback the callback function to apply to each
478
     *  node.
479
     */
480 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...
481
        if($node === null) {
482
            return;
483
        }
484
485
        $this->_inorder($node->left, $callback);
486
        if($callback !== null) {
487
            call_user_func($callback, $node);
488
        }
489
        $this->_inorder($node->right, $callback);
490
    }
491
492
    /**
493
     * Traverse in postorder. This is: first visit the left subtree,
494
     * then the right subtree and finally the root.
495
     *
496
     * @param Callable|null $callback the callback function to apply to each
497
     *  node.
498
     */
499
    public function postorder(Callable $callback = null) {
500
        $this->_postorder($this->root, $callback);
501
    }
502
503
    /**
504
     * Private postorder traverse method that is recursive and is called by
505
     * the public postorder method.
506
     *
507
     * @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...
508
     * @param Callable|null $callback the callback function to apply to each
509
     *  node.
510
     */
511 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...
512
        if($node === null) {
513
            return;
514
        }
515
        $this->_postorder($node->left, $callback);
516
        $this->_postorder($node->right, $callback);
517
        if($callback !== null) {
518
            call_user_func($callback, $node);
519
        }
520
    }
521
522
    /**
523
     * Binds to count() method. This is equal to make $this->tree->size().
524
     *
525
     * @return integer the tree size. 0 if it is empty.
526
     */
527
    public function count() {
528
        return $this->size;
529
    }
530
}