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\Nodes\SinglyLinkedListNode as Node; |
12
|
|
|
use DataStructures\Exceptions\FullException; |
13
|
|
|
use InvalidArgumentException; |
14
|
|
|
use Countable; |
15
|
|
|
|
16
|
|
|
/** |
17
|
|
|
* Queue |
18
|
|
|
* |
19
|
|
|
* Queue (FIFO) is a circular linked list that inserts at the end |
20
|
|
|
* of list and removes at the beginning. Insert and remove |
21
|
|
|
* are O(1), size and empty are also O(1). |
22
|
|
|
* |
23
|
|
|
* @author Siro Diaz Palazon <[email protected]> |
24
|
|
|
*/ |
25
|
|
|
class Queue implements Countable { |
26
|
|
|
private $head; |
27
|
|
|
private $tail; |
28
|
|
|
private $size; |
29
|
|
|
private $maxSize; |
30
|
|
|
|
31
|
|
View Code Duplication |
public function __construct($maxSize = 0) { |
|
|
|
|
32
|
|
|
if($maxSize < 0) { |
33
|
|
|
throw new InvalidArgumentException(); |
34
|
|
|
} |
35
|
|
|
$this->maxSize = $maxSize; |
36
|
|
|
$this->head = null; |
37
|
|
|
$this->tail = &$this->head; |
38
|
|
|
$this->size = 0; |
39
|
|
|
} |
40
|
|
|
|
41
|
|
|
/** |
42
|
|
|
* Returns the queue size. |
43
|
|
|
* |
44
|
|
|
* @return int the length |
45
|
|
|
*/ |
46
|
|
|
public function size() : int { |
47
|
|
|
return $this->size; |
48
|
|
|
} |
49
|
|
|
|
50
|
|
|
/** |
51
|
|
|
* Checks if the queue is empty. |
52
|
|
|
* |
53
|
|
|
* @return bool true if is empty, else false. |
54
|
|
|
*/ |
55
|
|
|
public function empty() : bool { |
56
|
|
|
return $this->size === 0; |
57
|
|
|
} |
58
|
|
|
|
59
|
|
|
/** |
60
|
|
|
* Add a new node at the end of the queue. |
61
|
|
|
* |
62
|
|
|
* @param mixed $data the data to store. |
63
|
|
|
* @throws DataStructures\Exceptions\FullException if the queue is full. |
64
|
|
|
*/ |
65
|
|
|
public function enqueue($data) { |
66
|
|
|
if($this->isFull()) { |
67
|
|
|
throw new FullException(); |
68
|
|
|
} |
69
|
|
|
|
70
|
|
|
$newNode = new Node($data); |
71
|
|
|
if($this->head === null) { |
72
|
|
|
$this->head = &$newNode; |
73
|
|
|
$this->tail = &$this->head; |
74
|
|
|
$newNode->next = &$this->tail; |
75
|
|
|
} else { |
76
|
|
|
$this->tail->next = &$newNode; |
77
|
|
|
$newNode->next = &$this->head; |
78
|
|
|
$this->tail = &$newNode; |
79
|
|
|
} |
80
|
|
|
$this->size++; |
81
|
|
|
} |
82
|
|
|
|
83
|
|
|
/** |
84
|
|
|
* Removes the first node in the queue. |
85
|
|
|
* |
86
|
|
|
* @return mixed |
87
|
|
|
*/ |
88
|
|
|
public function dequeue() { |
89
|
|
|
if($this->head === null) { |
90
|
|
|
return null; |
91
|
|
|
} |
92
|
|
|
|
93
|
|
|
if($this->head === $this->tail) { |
94
|
|
|
$temp = $this->head; |
95
|
|
|
$this->head = null; |
96
|
|
|
$this->tail = &$this->head; |
97
|
|
|
$this->size--; |
98
|
|
|
|
99
|
|
|
return $temp->data; |
100
|
|
|
} |
101
|
|
|
|
102
|
|
|
$temp = $this->head; |
103
|
|
|
$this->head = &$this->head->next; |
104
|
|
|
$this->tail->next = &$this->head; |
105
|
|
|
$this->size--; |
106
|
|
|
|
107
|
|
|
return $temp->data; |
108
|
|
|
} |
109
|
|
|
|
110
|
|
|
/** |
111
|
|
|
* Gets the element at the front of the queue without removing it. |
112
|
|
|
* |
113
|
|
|
* @return mixed |
114
|
|
|
*/ |
115
|
|
|
public function peek() { |
116
|
|
|
return ($this->head === null) ? null : $this->head->data; |
117
|
|
|
} |
118
|
|
|
|
119
|
|
|
/** |
120
|
|
|
* Returns true if is full the queue and false if there is |
121
|
|
|
* space available. |
122
|
|
|
* |
123
|
|
|
* @return bool |
124
|
|
|
*/ |
125
|
|
View Code Duplication |
public function isFull() { |
|
|
|
|
126
|
|
|
if($this->maxSize === 0) { |
127
|
|
|
return false; |
128
|
|
|
} |
129
|
|
|
|
130
|
|
|
return $this->size > 0 && $this->size >= $this->maxSize; |
131
|
|
|
} |
132
|
|
|
|
133
|
|
|
/** |
134
|
|
|
* Binds to count() method. This is equal to make $this->queue->size(). |
135
|
|
|
* |
136
|
|
|
* @return integer the queue size. 0 if it is empty. |
137
|
|
|
*/ |
138
|
|
|
public function count() { |
139
|
|
|
return $this->size; |
140
|
|
|
} |
141
|
|
|
} |
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.