Completed
Push — master ( b35ffe...d5e5c7 )
by Siro Díaz
01:25
created

SinglyLinkedList::rewind()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 3
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\Lists;
10
11
use DataStructures\Lists\Traits\{CountTrait, ArrayAccessTrait};
12
use DataStructures\Lists\Nodes\SinglyLinkedListNode;
13
use DataStructures\Exceptions\NotFoundException;
14
use OutOfBoundsException;
15
use Iterator;
16
17
/**
18
 * SinglyLinkedList
19
 *
20
 * SinglyLinkedList is a singly linked list that has
21
 * a pointer to the next node but last node points to null.
22
 *
23
 * @author Siro Diaz Palazon <[email protected]>
24
 */
25
class SinglyLinkedList extends ListAbstract {
26
    use ArrayAccessTrait;
27
    
28
    protected $head;
29
    private $position;
30
    private $current;
31
32 View Code Duplication
    public function __construct() {
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...
33
        $this->head = null;
34
        $this->size = 0;
35
        $this->position = 0;
36
        $this->current = &$this->head;
37
    }
38
39
    /**
40
     * {@inheritDoc}
41
     */
42
    protected function search($index) {
43
        if($index > $this->size - 1 || $index < 0) {
44
            throw new OutOfBoundsException();
45
        }
46
47
        $current = $this->head;
48
        $i = 0;
49 View Code Duplication
        while($i < $index && $current->next !== null) {
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...
50
            $current = $current->next;
51
            $i++;
52
        }
53
54
        return $current;
55
    }
56
57
    /**
58
     *
59
     */
60 View Code Duplication
    public function searchLast() {
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...
61
        if($this->head === null) {
62
            return null;
63
        }
64
65
        $current = $this->head;
66
        while($current->next !== null) {
67
            $current = $current->next;
68
        }
69
70
        return $current;
71
    }
72
73
    /**
74
     * Generator for retrieve all nodes stored.
75
     * 
76
     * @return null if the head is null (or list is empty)
77
     */
78 View Code Duplication
    public function getAll() {
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...
79
        if($this->head === null) {
80
            return;
81
        }
82
83
        $current = $this->head;
84
        while($current !== null) {
85
            yield $current->data;
86
            $current = $current->next;
87
        }
88
    }
89
90
    /**
91
     * {@inheritDoc}
92
     */
93
    public function contains($data) : bool {
94
        if($this->empty()) {
95
            return false;
96
        }
97
98
        $current = $this->head;
99
        while($current !== null) {
100
            if($current->data === $data) {
101
                return true;
102
            }
103
            $current = $current->next;
104
        }
105
106
        return false;
107
    }
108
109
    /**
110
     * {@inheritDoc}
111
     */
112 View Code Duplication
    public function indexOf($data) {
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...
113
        if($this->head === null) {
114
            return false;
115
        }
116
        
117
        $current = $this->head;
118
        $i = 0;
119
        
120
        while($i < $this->size) {
121
            if($current->data === $data) {
122
                return $i;
123
            }
124
125
            $current = $current->next;
126
            $i++;
127
        }
128
129
        return false;
130
    }
131
132
    /**
133
     * {@inheritDoc}
134
     */
135 View Code Duplication
    public function lastIndexOf($data) {
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...
136
        if($this->head === null) {
137
            return false;
138
        }
139
        
140
        $current = $this->head;
141
        $i = 0;
142
        $pos = false;
143
        while($i < $this->size) {
144
            if($current->data == $data) {
145
                $pos = $i;
146
            }
147
148
            $current = $current->next;
149
            $i++;
150
        }
151
152
        return $pos;
153
    }
154
155
    /**
156
     * {@inheritDoc}
157
     */
158
    public function remove($data) {
159
        $current = &$this->head;
160
        $prev = null;
161
        $i = 0;
162
        
163
        if($this->head === null) {
164
            throw new NotFoundException();
165
        }
166
167
        if($this->head->data === $data) {
168
            $this->head = &$this->head->next;
169
            $this->size--;
170
            return $data;
171
        }
172
        
173 View Code Duplication
        while($i < $this->size) {
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...
174
            if($current->data === $data) {
175
                $prev->next = &$current->next;
176
                $this->size--;
177
178
                return $data;
179
            }
180
181
            $prev = $current;
182
            $current = $current->next;
183
        }
184
185
        throw new NotFoundException();
186
    }
187
188
    /**
189
     * Add a new node in the specified index.
190
     *
191
     * @param integer $index the position.
192
     * @param mixed $data the data to be stored.
193
     */
194 View Code Duplication
    protected function insertAt($index, $data) {
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...
195
        $newNode = new SinglyLinkedListNode($data);
196
        $current = $this->head;
197
        $prev = null;
198
        $i = 0;
199
        while($i < $index) {
200
            $prev = $current;
201
            $current = $current->next;
202
            $i++;
203
        }
204
        
205
        $prev->next = &$newNode;
206
        $newNode->next = &$current;
207
    }
208
209
    protected function insertEnd($data) {
210
        $newNode = new SinglyLinkedListNode($data);
211 View Code Duplication
        if($this->head === null) {
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...
212
            $this->head = &$newNode;
213
            $this->current = &$this->head;
214
        } else {
215
            $current = $this->head;
216
            while($current->next !== null) {
217
                $current = $current->next;
218
            }
219
            $current->next = &$newNode;
220
        }
221
    }
222
223
    /**
224
     * {@inheritDoc}
225
     */
226 View Code Duplication
    protected function insertBeginning($data) {
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...
227
        $newNode = new SinglyLinkedListNode($data);
228
        if($this->head === null) {
229
            $this->head = &$newNode;
230
        } else {
231
            $newNode->next = $this->head;
232
            $this->head = &$newNode;
233
        }
234
    }
235
236
    /**
237
     * Delete a node in the given position and returns it back.
238
     *
239
     * @param integer $index the position.
240
     * @throws OutOfBoundsException if index is negative
241
     *  or is greater than the size of the list.
242
     */
243
    public function delete($index) {
244
        if($index < 0) {
245
            throw new OutOfBoundsException();
246
        }
247
        if($this->head === null) {
248
            return null;
249
        }
250
251
        if($index >= $this->size) {
252
            return null;    // It should return an exception
253
        }
254
255
        if($index === 0) {
256
            $node = $this->head;
257
            $this->head = $this->head->next;
258
            $this->current = &$this->head;
259
            $this->size--;
260
            return $node->data;
261
        }
262
        
263
        $i = 0;
264
        $current = $this->head;
265
        $prev = $current;
266 View Code Duplication
        while($i < $index && $current->next !== null) {
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...
267
            $prev = $current;
268
            $current = $current->next;
269
        }
270
271
        if($index === $this->size - 1) {
272
            $prev->next = null;
273
            $this->size--;
274
            return $current->data;
275
        } else {
276
            $prev->next = $current->next;
277
        }
278
        $this->size--;
279
280
        return $prev->data;
281
    }
282
283
    protected function deleteBeginning() {}
284
285
    protected function deleteAt($index) {}
286
287
    protected function deleteEnd() {}
288
289
    
290
291
    /**
292
     * Reset the cursor position.
293
     */
294
    public function rewind() {
295
        $this->position = 0;
296
        $this->current = $this->head;
297
    }
298
299
    /**
300
     * Returns the current node data.
301
     *
302
     * @return mixed
303
     */
304
    public function current() {
305
        return $this->current->data;
306
    }
307
308
    /**
309
     * Key or index that indicates the cursor position.
310
     *
311
     * @return integer The current position.
312
     */
313
    public function key() {
314
        return $this->position;
315
    }
316
317
    /**
318
     * Move the cursor to the next node and increments the
319
     * position counter.
320
     */
321
    public function next() {
322
        ++$this->position;
323
        $this->current = $this->current->next;
324
    }
325
326
    /**
327
     * Returns if the current pointer position is valid.
328
     *
329
     * @return boolean true if pointer is not last, else false.
330
     */
331
    public function valid() {
332
        return $this->current !== null;
333
    }
334
}