Queues
Outline Review of Stacks Queues queue operations exceptional circumstances algorithms with queues
Stack ADT One access point: the top Massively useful push an item onto the top look at the top item pull an item off the top Massively useful procedure activation records balancing, infix to postfix, postfix evaluation maze tracing
Insertion and Deletion Order Stack: last in is first out (LIFO) push A, push B, push C pop C, pop B, pop A out in reverse order that they went in Queue: first in is first out (FIFO) add A, add B, add C remove A, remove B, remove C out in same order that they went in
Queue Operations Queues require these operations add at back (enqueue, put, insert) .add(item) delete from front (dequeue, get) .remove() Typically have some others check if empty .isEmpty() inspect front element (getFront, peek) .front() empty it out .clear() get size .size()
A Queue Arranged left to right front at the left Old items are removed or dequeued at front myQueue.remove() New items are inserted or enqueued at back myQueue.add(99) Queue Back Front 17 24 81 12 5 7 17 12 8
A Queue Arranged left to right front at the left Old items are removed or dequeued at front myQueue.remove() New items are inserted or enqueued at back myQueue.add(99) Queue Back Front 24 81 12 5 7 17 12 8
A Queue Arranged left to right front at the left Old items are removed or dequeued at front myQueue.remove() New items are inserted or enqueued at back myQueue.add(99) Queue Back Front 24 81 12 5 7 17 12 8 99
Real World Queues Any line-up Assembly line bank, ticket window, amusement ride (except – people might give up & leave) Assembly line chassis inserted at one end completed vehicle comes off the other
FILO and LILO Stack operations all at one end Last element in the stack is the first one out Last In, First Out = LIFO AKA FILO = First In, Last Out Last element in a queue is last one out Last In, Last Out = LILO AKA FIFO = First In, First Out
Exercise Draw the queues that result from the following operations Start with empty each time add A, add B, add C, remove, remove add 1, add 2, remove, add 3, add 4
Exceptional Circumstances Similar to stacks: try to remove/get front of empty queue try to add to a full queue try to add a null Solutions similar as well: return null / throw an exception return false / throw an exception two versions of remove and front
Java Queues java.util.Queue is an interface cannot be instantiated Operations that throw exceptions add(e), remove(), element() Operations that return a special value offer€, poll(), peek() Other queue operations isEmpty(), size()
Queues in Java Instantiate using ArrayDeque or LinkedList Queue<String> words = new ArrayDeque<>(); Queue<Integer> numbers = new LinkedList<>(); Queue interface will prevent you from using non-Queue operations Methods expecting Queues should, of course, use Queue as the parameter type private static void process(Queue q) { … } will accept ArrayDeques and LinkedLists
Using Queues File server Railway sidings Wire routing (shortest path) Image component labeling Radix Sort
Wire Routing Problem Need to connect two locations on a device can’t go over existing components want shortest path 000000654560 011106543110 01110543S1F0 000011143450 001111051110 001110001110 000000011110 000000000000 000011110000
Wire Routing Problem Represent device by 0-1 matrix 0 = free space 1 = component Need start & end points locations in matrix (2, 8) and (2, 10) 000000000000 011100000110 011100000100 000011100000 001111001110 001110001110 000000011110 000011110000
Wire Routing Problem Two Pass Method to RouteWire(matrix, start, end) // find distances from start LabelDistances(matrix, start, end) // find path from end back to start FindRouteBack(matrix, start, end)
Distance Pass add start cell, labeled 2 [(2, 8)] remove start cell (=2), add its neighbours, labeled 3 [(1, 8), (3, 8), (2, 7)] remove next cell (=3), add its neighbours, labeled 4 [(3, 8), (2, 7), (0, 8), (1, 7)] 1 2 3 4 5 6 7 8 9 a 000000004000 011100043110 0111000321e0 000011103000 001111001110 001110001110 000000011110 000000000000 000011110000 000000000000 011100003110 0111000321e0 000011103000 001111001110 001110001110 000000011110 000011110000 000000000000 011100000110 0111000021e0 000011100000 001111001110 001110001110 000000011110 000011110000 000000000000 011100000110 01110000s1e0 000011100000 001111001110 001110001110 000000011110 000011110000
Distance Pass Repeat until you reach goal 0123456789ab Repeat until you reach goal or until queue is empty Remove (3, 10), labeled 5, label its neighbours 6 [(4, 7), (2, 5), (0, 10), …] add (2, 10) = end can stop now 1 2 3 4 5 6 7 8 9 a 000000654560 011106543110 011105432160 000011143450 001111051110 001110001110 000000011110 000000000000 000011110000
Doesn’t stop as early as it could Label Distances Code to LabelDistances(matrix, start, end) matrix[start] 2; q.add(start); while (!q.empty()) if (q.front() = end) break; LabelAndAddNeighbours(q, matrix); q.remove(); if (q.empty()) throw exception(“No path found”); Doesn’t stop as early as it could
Label and Add Neighbours to LabelAndAddNeighbours(q, matrix) current q.front(); value 1 + matrix[current]; for each neighbour of current: if matrix[neighbour] = 0: set matrix[neighbour] to value; q.add(neighbour)
Path Finding Start at goal Pick a neighbour labeled one less than you Repeat until reach start in this example a single path 000000654560 011106543110 011105432160 000011143450 001111051110 001110001110 000000011110 000000000000 000011110000
Finding Path Back to FindRouteBack(matrix, start, end) current end; while (current != start) label matrix[current]; matrix[current] 1; // now used current FindNeighbour(matrix, current, label–1); matrix[start] 1; // start used, too
Exercises Show how the queue develops for the rest of the example above assume always look north, east, south, west assume stop as soon as the end cell labeled To think about how could we rewrite the code above to stop as soon as the end cell gets labeled?
Image Component Labeling Select area with one colour in photo magic wand tool find buildings/roads on satellite photo separate foreground items for computer vision Simplified version: dot-matrix image (0s and 1s only) harder versions handle various colours require a “distance” calculation for “close” colours
Image Component Example 000000000000 011100000110 011100000100 000011100000 001111001110 001110001110 000000011110 000011110000 000000000000 022200000330 022200000300 000044400000 004444005550 004440005550 000000055550 000066660000
Matrix Scan Method Start component counter at 1 Scan thru matrix looking for unlabeled cells (it’ll be a cell with a 1 in it) increment the current component counter set cell to the current component count put cell on a queue process the queue
Queue Processing Method Dequeue a cell For each of its four neighbours if its pixel is 1 set the pixel to the current component # add it to the queue Repeat until the queue is empty
Scanning for an Unlabeled Pixel Start counter at 1 First 1 pixel found is at 1,1 Increment counter to 2 Set cell 1.1 to 2 1 2 3 4 5 6 7 8 9 a 000000000000 011100000110 011100000100 000011100000 001111001110 001110001110 000000011110 000011110000
Scanning for an Unlabeled Pixel Start counter at 1 First 1 pixel found is at 1,1 Increment counter to 2 Set cell 1.1 to 2 Enqueue it Queue = [1.1] Process the queue 1 2 3 4 5 6 7 8 9 a 000000000000 021100000110 011100000100 000011100000 001111001110 001110001110 000000011110 000011110000
Processing the List Remove 1.1 Neighbours are: Cell 0.1 is a zero 0123456789ab Queue = [1.1] Remove 1.1 Queue = [] Neighbours are: 0.1, 1.2, 2.1, 1.0 Cell 0.1 is a zero not part of a component 1 2 3 4 5 6 7 8 9 a 000000000000 021100000110 011100000100 000011100000 001111001110 001110001110 000000011110 000011110000
Processing the List Still working on 1.1 Next neighbour is 1.2 0123456789ab Still working on 1.1 Queue = [] Next neighbour is 1.2 1.2 is a 1 set it to 2 add it to the queue Queue = [1.2] 1 2 3 4 5 6 7 8 9 a 000000000000 021100000110 011100000100 000011100000 001111001110 001110001110 000000011110 000011110000
Processing the List Still working on 1.1 Next neighbour is 1.2 0123456789ab Still working on 1.1 Queue = [] Next neighbour is 1.2 1.2 is a 1 set it to 2 add it to the queue Queue = [1.2] 1 2 3 4 5 6 7 8 9 a 000000000000 022100000110 011100000100 000011100000 001111001110 001110001110 000000011110 000011110000
Processing the List Still working on 1.1 Next neighbour is 2.1 0123456789ab Still working on 1.1 Queue = [1.2] Next neighbour is 2.1 2.1 is a 1 set it to 2 1 2 3 4 5 6 7 8 9 a 000000000000 022100000110 011100000100 000011100000 001111001110 001110001110 000000011110 000011110000
Processing the List Still working on 1.1 Next neighbour is 2.1 0123456789ab Still working on 1.1 Queue = [1.2] Next neighbour is 2.1 2.1 is a 1 set it to 2 add it to the queue Queue = [1.2, 2.1] 1 2 3 4 5 6 7 8 9 a 000000000000 022100000110 021100000100 000011100000 001111001110 001110001110 000000011110 000011110000
Processing the List Still working on 1.1 Next neighbour is 1.0 0123456789ab Still working on 1.1 Queue = [1.2, 2.1] Next neighbour is 1.0 1.0 is a 0 not part of the component No more neighbours for 1.1 1 2 3 4 5 6 7 8 9 a 000000000000 022100000110 021100000100 000011100000 001111001110 001110001110 000000011110 000011110000
Processing the List Remove 1.2 1.3 is a 1: process it 0123456789ab Queue = [1.2, 2.1] Remove 1.2 Queue = [2.1] 1.3 is a 1: process it Queue = [2.1, 1.3] 2.2 is a 1: process it Queue = [2.1, 1.3, 2.2] 1 2 3 4 5 6 7 8 9 a 000000000000 022100000110 021100000100 000011100000 001111001110 001110001110 000000011110 000011110000
Processing the List Remove 2.1 None of its neighbours is 1 0123456789ab Queue = [2.1, 1.3, 2.2] Remove 2.1 Queue = [1.3, 2.2] None of its neighbours is 1 1 2 3 4 5 6 7 8 9 a 000000000000 022200000110 022100000100 000011100000 001111001110 001110001110 000000011110 000011110000
Processing the List Remove 1.3 2.3 is a 1 Queue = [1.3, 2.2] 0123456789ab Queue = [1.3, 2.2] Remove 1.3 Queue = [2.2] 2.3 is a 1 Queue = [2.2, 2.3] 1 2 3 4 5 6 7 8 9 a 000000000000 022200000110 022100000100 000011100000 001111001110 001110001110 000000011110 000011110000
Processing the List Remove 2.2 None of its neighbours is 1 0123456789ab Queue = [2.2, 2.3] Remove 2.2 Queue = [2.3] None of its neighbours is 1 1 2 3 4 5 6 7 8 9 a 000000000000 022200000110 022200000100 000011100000 001111001110 001110001110 000000011110 000011110000
Processing the List Remove 2.3 None of its neighbours is 1 0123456789ab Queue = [2.3] Remove 2.3 Queue = [] None of its neighbours is 1 1 2 3 4 5 6 7 8 9 a 000000000000 022200000110 022200000100 000011100000 001111001110 001110001110 000000011110 000011110000
Processing the List Queue is empty Return to scanning matrix 0123456789ab Queue = [] Queue is empty component has been completely labeled Return to scanning matrix cell 1.2 is labeled next unlabeled cell is 1.9 1 2 3 4 5 6 7 8 9 a 000000000000 022200000310 022200000100 000011100000 001111001110 001110001110 000000011110 000011110000
Pseudo-Code To LabelComponents(matrix): compNo 1; for r 1 .. matrix.numRows for c 1 .. matrix.numCols if (mat[r][c] = 1) compNo++; LabelComponent(matrix, r, c, compNo)
Pseudo-Code to LabelComponent(matrix, r, c, compNo) queue q [<r, c>] while (!q.empty()) <r1, c1> = q.remove(); for each neighbour <r2,c2> of <r1,c1> if (matrix[r2][c2] == 1) matrix[r2][c2] = compNo q.add(<r2,c2>)
Questions