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

SimpleLinkedList::count()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 3
c 0
b 0
f 0
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\Lists;
10
11
use DataStructures\Lists\Traits\{CountTrait, ArrayAccessTrait};
12
use DataStructures\Lists\Nodes\SimpleLinkedListNode as Node;
13
use DataStructures\Lists\Interfaces\ListInterface;
14
use OutOfBoundsException;
15
use Iterator;
16
17
/**
18
 * SimpleLinkedList
19
 *
20
 * SimpleLinkedList 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 SimpleLinkedList implements ListInterface {
26
    use CountTrait, ArrayAccessTrait;
27
    
28
    private $head;
29
    private $size;
30
    private $position;
31
    private $current;
32
33 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...
34
        $this->head = null;
35
        $this->size = 0;
36
        $this->position = 0;
37
        $this->current = &$this->head;
38
    }
39
40
    /**
41
     * Adds at the end of the list new node containing
42
     * the data to be stored.
43
     *
44
     * @param mixed $data The data
45
     */
46
    public function push($data) {
47
        $newNode = new Node($data);
48 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...
49
            $this->head = &$newNode;
50
            $this->current = &$this->head;
51
        } else {
52
            $current = $this->head;
53
            while($current->next !== null) {
54
                $current = $current->next;
55
            }
56
            $current->next = &$newNode;
57
        }
58
59
        $this->size++;
60
    }
61
62
    /**
63
     * Gets the data stored in the position especified.
64
     *
65
     * @param integer $index Index that must be greater than 0
66
     *  and lower than the list size.
67
     * @return mixed The data stored in the given index
68
     * @throws OutOfBoundsException if index is out bounds.
69
     */
70
    public function get($index) {
71
        if($index > $this->size - 1 || $index < 0) {
72
            throw new OutOfBoundsException();
73
        }
74
        
75
76
        $current = $this->head;
77
        $i = 0;
78 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...
79
            $current = $current->next;
80
            $i++;
81
        }
82
83
        return $current->data;
84
    }
85
86
    /**
87
     * Generator for retrieve all nodes stored.
88
     * 
89
     * @return null if the head is null (or list is empty)
90
     */
91
    public function getAll() {
92
        if($this->head === null) {
93
            return;
94
        }
95
96
        $current = $this->head;
97
        while($current !== null) {
98
            yield $current->data;
99
            $current = $current->next;
100
        }
101
    }
102
103
    /**
104
     * Insert a node in the specified list position.
105
     *
106
     * @param integer $index position
107
     * @param mixed $data data to be saved
108
     */
109
    public function insert($index, $data) {
110
        if($this->head === null) {
111
            return $this->push($data);
112
        }
113
114
        $newNode = new Node($data);
115
        if($index === 0) {
116
            $aux = $this->head;
117
            $this->head = &$newNode;
118
            $newNode->next = &$aux;
119
            $this->current = &$this->head;
120
        } else {
121
            $i = 0;
122
            $current = $this->head;
123
            $prev = $current;
124 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...
125
                $prev = $current;
126
                $current = $current->next;
127
                $i++;
128
            }
129
130
            $prev->next = &$newNode;
131
            $newNode->next = &$current;
132
        }
133
134
        $this->size++;
135
    }
136
137
    /**
138
     * Delete a node in the given position and returns it back.
139
     *
140
     * @param integer $index the position.
141
     * @throws OutOfBoundsException if index is negative
142
     *  or is greater than the size of the list.
143
     */
144
    public function delete($index) {
145
        if($index < 0) {
146
            throw new OutOfBoundsException();
147
        }
148
        if($this->head === null) {
149
            return null;
150
        }
151
152
        if($index >= $this->size) {
153
            return null;    // It should return an exception
154
        }
155
156
        if($index === 0) {
157
            $node = $this->head;
158
            $this->head = $this->head->next;
159
            $this->current = &$this->head;
160
            $this->size--;
161
            return $node->data;
162
        }
163
        
164
        $i = 0;
165
        $current = $this->head;
166
        $prev = $current;
167 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...
168
            $prev = $current;
169
            $current = $current->next;
170
        }
171
        $prev->next = $current->next;
172
        $this->size--;
173
174
        return $prev->data;
175
    }
176
177
    /**
178
     * Removes and returns the last node in the list.
179
     *
180
     * @return mixed data in node.
181
     */
182
    public function pop() {
183
        return $this->delete($this->size - 1);
184
    }
185
186
    /**
187
     * Remove all nodes of the list using shift.
188
     */
189
    public function clear() {
190
        while($this->head !== null) {
191
            $this->shift();
192
        }
193
    }
194
195
    /**
196
     * Converts/exports the list content into array type.
197
     *
198
     * @return array data stored in all nodes.
199
     */
200
    public function toArray() : array {
201
        $arr = [];
202
        foreach($this->getAll() as $node) {
203
            $arr[] = $node;
204
        }
205
206
        return $arr;
207
    }
208
209
    /**
210
     * Adds at the beginning a node in the list.
211
     *
212
     * @param mixed $data
213
     * @return mixed the data stored.
214
     */
215
    public function unshift($data) {
216
        $this->insert(0, $data);
217
    }
218
219
    /**
220
     * Deletes the first node of the list and returns it.
221
     *
222
     * @return mixed the data.
223
     */
224
    public function shift() {
225
        return $this->delete(0);
226
    }
227
228
    /**
229
     * Reset the cursor position.
230
     */
231
    public function rewind() {
232
        $this->position = 0;
233
        $this->current = $this->head;
234
    }
235
236
    /**
237
     * Returns the current node data.
238
     *
239
     * @return mixed
240
     */
241
    public function current() {
242
        return $this->current->data;
243
    }
244
245
    /**
246
     * Key or index that indicates the cursor position.
247
     *
248
     * @return integer The current position.
249
     */
250
    public function key() {
251
        return $this->position;
252
    }
253
254
    /**
255
     * Move the cursor to the next node and increments the
256
     * position counter.
257
     */
258
    public function next() {
259
        ++$this->position;
260
        $this->current = $this->current->next;
261
    }
262
263
    /**
264
     * Returns if the current pointer position is valid.
265
     *
266
     * @return boolean true if pointer is not last, else false.
267
     */
268
    public function valid() {
269
        return $this->current !== null;
270
    }
271
}