2. # todo
- php impl of Queue as Linked List
- persistent queue (using 5 stacks)
- persistent queue (using 6 stacks)
- deque impl (double-end queue)
- change rair => tail, start => head, etc
- add gif-animation for algo
2
3. Queue: definition
data structure
set of items
earliest added item may be accessed (FIFO)
has two ends (head and rair/tail)
push (into tail) and pop (from head)
3
4. Queue: examples IRL
- lines of people (line in a grocery store, buy a movie ticket)
- conveyor belt
- waiting lists
- access to shared resources (e.g. printer jobs)
- things that are in "time order"
- events in Windows
- keyboard strokes
- video frames
4
6. Queue: interface
enqueue (put) - add to the tail
dequeue (get + delete) - get from the head
empty(Q):bool
count(Q):int
front(Q):item - peek (just get)
6
7. Queue: axioms
new() returns a queue
add(v, new()).isEmpty() = false
front(add(v, new())) = v
remove(add(v, new())) = new()
front(add(v, add(w, Q))) = front(add(w, Q))
remove(add(v, add(w, Q))) = add(v, remove(add(w, Q)))
Q - queue; v and w - values;
7
8. Queue: basic example
initial -> | | | | (assume 3 element capacity)
enqueue(a) -> |a| | |
enqueue(b) -> |a|b| |
enqueue(c) -> |a|b|c|
dequeue() -> | |b|c| (returns a)
dequeue() -> | | |c| (returns b)
dequeue() -> | | | | (returns c) (all gone!)
head |a|b|c| tail
8
10. as array and two integer variables start and end
start = head of queue
end = element that will be filled when new el will come
@todo on images replace front->start, back->end
Queue: implementation using Array
10
11. Queue: implementation using Array
enqueue(item): item => q[end], end++
dequeue(): item <= q[start], start++
if Queue not full
- put element at end Q[tail] <- elem
- increment tail tail <- tail + 1
11
12. int A[10]
front = -1
tail = -1
function isEmpty() { front == -1 && tail == -1 }
function isFull() { tail == size(A)-1 }
function enqueue(v) {
if isFull() -> error Queue is full
if isEmpty() front <- tail <- 0 else tail+=1
A[tail] = v
}
Queue: implementation using Array
12
16. Queue: implementation using Array
function dequeue() {
if isEmpty() -> error Queue is empty
elseif front == tail
front <- rear <- -1
else
front += 1
}
16
19. no end on array
wrapping around
ring buffer / circular buffer
push/pop - O(1)
when item inserted to rair, tails’s pointer moves upwards
when item deleted, head’s pointer moves downwards
current_position = i
next_position = (i + 1) % N
prev_position = (N + i - 1) % N
Queue: implementation Cyclic Array
19
20. function isFull() {
(tail + 1 ) % N == head
}
function enqueue(v) {
if isFull() -> error Queue is full
if isEmpty() front <- tail <- 0
else tail = (tail + 1) % N
A[tail] = v
}
function dequeue() {
if isEmpty() -> error Queue is empty
elseif front == tail front <- rear <- -1
else front = (front + 1) % N
}
Queue: implementation Cyclic Array
20
21. Queue: implementation using Array: pros & cons
pros
- minor memory savings (compared with LinkedList impl)
- easier to develop
cons
- fixed size
- when is full, need create new arary, with reallocation
of memory and copy all els to the new array (costly
process, O(n))
21
22. Queue: implementation using Linked List
one way Linked List (based on the work with dynamic memory)
insertion/removal: at head O(1), at tail O(n)
http://www.cosc.canterbury.ac.nz/mukundan/dsal/LinkQueueAppl.html
22
23. Queue: implementation using Linked List
insert: create a node, update tail pointer
traversal is complex, O(n)
23
25. class Node {
Object data
Node next
}
class Queue {
Node front
Node rear
}
isEmpty() {
return rear == null
}
Queue: implementation using Linked List
25
function enqueue(x) {
newNode = new Node
newNode->data = x
if isEmpty()
front = newNode
else
rear->next = newNode
rear = newNode
}
function dequeue(d) {
temp = front
if front = null { return }
if front == rear {
front = rear = null
}
else {
front = front->next
}
free(temp)
}
27. Queue: implementation using Linked List: pros & cons
pros
- size is limited by memory capacity
cons
- requires more memory
- more memory is fragmented
27
29. Queue: implementation using 2 Stacks: example
procedure enqueue(x):
S1.push(x)
function dequeue():
if S1 is empty and S2 is empty:
error: stack is empty
while S1 isn’t empty:
S2.push(S1.pop())
return S2.pop()
29
30. Queue: implementation using 2 Stacks: pros & cons
Эту реализацию несложно модифицировать для получения минимума в
текущей очереди за O(1).
Если leftStack не пуст, то операция pop может выполняться O(n) времени,
в отличии от других реализаций, где pop всегда выполняется за O(1).
30
33. pros
- ??? O(1)
- can be improved to persistent queue, if use persistent stack
cons
- longer than the average operation is performed
- more memory consumption
- the greater complexity of implementation
Queue: implementation using 6 Stacks: pros & cons
33
37. class Queue {
public function enqueue($item) { }
public function dequeue() { }
public function count() { }
}
Queue: implementation in php
37
38. class Queue {
private $_queue = array();
public function enqueue($item) {
$this->_queue[] = $item;
}
public function dequeue() {
return array_shift($this->_queue);
}
public function count() {
return count($this->_queue);
}
}
Queue: implementation in php (using Array)
38
39. class Queue {
private $_queue = array();
private $_headPosition = null,
$_tailPosition = null;
public function enqueue($item) {
$this->_queue[] = $item;
if ($this->count() == 1) {
$this->_headPosition
= 0;
$this->_tailPosition
= 0;
}
$this->rewind();
}
public function count() {
return count($this->_queue);
}
Queue: implementation in php (using Array)
39
public function dequeue() {
$item = $this->_queue[$this->_headPositio
$this->_headPosition++;
return $item;
}
public function hasNext() {
return isset($this->_queue[$this->_headPo
}
public function rewind() {
$this->_tailPosition = $this->_headPositi
}
}
46. Priority Queue: implementation as Unordered Array
class QueueAsUnorderedArray {
...foreach..
}
http://algs4.cs.princeton.edu/24pq/UnorderedArrayMaxPQ.jav
a.html
46
47. Priority Queue: implementation as Ordered Array
class QueueAsOrderedArray {
...foreach..
}
http://algs4.cs.princeton.edu/24pq/OrderedArrayMaxPQ.java.
html
47
50. SplPriorityQueue impl using max-heap
Priority Queue: php (SPL)
50
public bool isEmpty ()
public mixed key ()
public void next ()
public void recoverFromCorruption ()
public void rewind ()
public void setExtractFlags ($flags)
public mixed top ()
public bool valid ()
}
class SplPriorityQueue implements Iterator, Countable {
public __construct ()
public int compare ($priority1, $priority2)
public int count ()
public mixed current ()
public mixed extract ()
public void insert ($value, $priority)
55. double-ended queue
els can be added to head or tail
is generalization of both stack and queue
DEQueue: definition
55
56. input restricted deque
- restricts insertion of els at one end only
- allow deletion of both ends
output restricted deque
- restricts deletion of els at one end only
- allows insertion to both ends
Deque: types
56
57. double linked-list (with two additional reference
variables to refer the first and last items)
Deque: implementation
57
first will be removed element that was added firstly
дисциплиной доступа
когда нужно совершить какие-то действия в порядке их поступления, выполнив их последовательно
basic operations
enqueue — поставить в очередь
аксіоматична семантика
семантика = значення слів і їх складових частин
аксіома = твердження, яке сприймається як істинне
визначається поведінка АДТ через аксіомі
Способы реализации
array-based / reference-based
linear time for both operations
деление по модулю
один из самых простых и эффективных способов организовать FIFO, без использования динамической памяти.
the maximum number of els limited by array size
collection of nodes
memory is an important resource; we should avoid blocking memory unnecessary
добавление/удаление элементов идет строго с соответствующих его концов
to find any - need to start at head
Персистентная очередь
Персистентная очередь
LIFO/FIFO is frozen SplStack/SplQueue
LIFO/FIFO is frozen SplStack/SplQueue
stack: each inserted element is monotonically increasing
queue: the priority of each inserted element is monotonically decreasing
ordered array = the largest item is on tail
ordered array = the largest item is on tail
ordered array = the largest item is on tail
to insert => insert it at the rear end of the queue
to delete => find the position of min el, and
mark as deleted (lazy deletion)
shift all els past the deleted el by one position and decrement rear