Lecture 04 - Stacks and Queues
Lecture 04 - Stacks and Queues
International University
School of Computer Science and Engineering
FR I D AY , 1 1 O CT O BE R 2 0 24 2
What is a stack?
FR I D AY , 1 1 O CT O BE R 2 0 24 3
Stack - Introduction
• Accessible item ?
• Last inserted item
• Last in, first out (LIFO)
• Operations
• Push ?
• Pop ?
• Peek / Top?
• Properties
• Stack Overflow (Full)
• Stack Underflow (Empty)
FR I D AY , 1 1 O CT O BE R 2 0 24 4
Operations on a stack
FR I D AY , 1 1 O CT O BE R 2 0 24 5
Stack info
FR I D AY , 1 1 O CT O BE R 2 0 24 6
Operations – Push (visual demo)
FR I D AY , 1 1 O CT O BE R 2 0 24 7
Operations – Pop (visual demo)
FR I D AY , 1 1 O CT O BE R 2 0 24 8
Operations – Peek (visual demo)
FR I D AY , 1 1 O CT O BE R 2 0 24 9
Check Stack?
Empty Full
• top = ? • top = ?
• -1 • maxSize - 1
FR I D AY , 1 1 O CT O BE R 2 0 24 10
Stack Exceptions
FR I D AY , 1 1 O CT O BE R 2 0 24 12
Stack in computer memory
• How does a stack in memory actually work?
• Each time a method is called, an activation record (AR) is
allocated for it. This record usually contains the following
information:
• Parameters and local variables used in the called method.
• A dynamic link, which is a pointer to the caller's activation record.
• Return address to resume control by the caller, the address of the
caller’s instruction immediately following the call.
• Return value for a method not declared as void. Because the size of
the activation record may vary from one call to another, the
returned value is placed right above the activation record of the
caller.
FR I D AY , 1 1 O CT O BE R 2 0 24 13
Stack in computer memory
FR I D AY , 1 1 O CT O BE R 2 0 24 14
Array-based Stack - 1
…
S
0 1 2 top
Array-based stack
FR I D AY , 1 1 O CT O BE R 2 0 24 15
Array-based Stack - 2
…
S
0 1 2 top
Array-based stack may become full
FR I D AY , 1 1 O CT O BE R 2 0 24 16
Array implementation of a stack
class ArrayStack { public boolean isEmpty() {
protected Object[] a; int top, max; return(top==-1);
public ArrayStack() { }
this(50); public boolean isFull() {
} return(top==max-1);
public ArrayStack(int max1) { }
max = max1; public void clear() {
a = new Object[max]; top=-1;
top = -1; }
} public void push(Object x) {
protected boolean grow() { if(isFull() && !grow()) return;
int max1 = max + max/2; a[++top] = x;
Object[] a1 = new Object[max1]; }
if(a1 == null) return(false); public Object top() throws EmptyStackException {
for(int i =0; i<=top; i++) { if(isEmpty()) throw new EmptyStackException();
a1[i] = a[i]; return(a[top]);
} }
a = a1; public Object pop() throws EmptyStackException {
return(true); if(isEmpty()) throw new EmptyStackException();
} Object x = a[top];
public boolean isEmpty() { top--;
return(top==-1); return(x);
} }
FR I D AY , 1 1 O CT O BE R 2 0 24 17
Stack - Application
• Delimiter Matching
• 100 * (100 – 50) ➔ Correct
• [100 * (100 – 50)] /2 ➔ Correct
• [100 * (100 – 50)} /2 ➔ Incorrect, error on }
• [100 * (100 – 50) /2 ➔ Incorrect, error on [
• (100 * (100 – 50))) /2 ➔ Incorrect, error on )
FR I D AY , 1 1 O CT O BE R 2 0 24 21
How would you do it?
• Reversing an array
250
200
150
120 250 200 150 120 100
100
FR I D AY , 1 1 O CT O BE R 2 0 24 22
Validate expression using stack - 1
• We consider arithmetic expressions that • The following examples further illustrate
may contain various pairs of grouping this concept:
symbols, such as • Correct: ( )(( )){([( )])}
• Parentheses: “(” and “)” • Correct: ((( )(( )){([( )])}))
• Braces: “{” and “}” • Incorrect: )(( )){([( )])}
• Brackets: “[” and “]” • Incorrect: ({[ ])}
• Each opening symbol must match its • Incorrect: (
corresponding closing symbol. For
example,
• a left bracket, “[,” must match a
corresponding right bracket, “],” as in the
following expression
• [(5+x)−(y+z)].
FR I D AY , 1 1 O CT O BE R 2 0 24 23
Validate expression using stack - 2
• An Algorithm for Matching Delimiters:
• An important task when processing arithmetic expressions is to make sure their delimiting
symbols match up correctly.
• We can use a stack to perform this task with a single left-to-right scan of the original string.
• Each time we encounter an opening symbol, we push that symbol onto the stack, and each time
we encounter a closing symbol, we pop a symbol from the stack (assuming it is not empty) and
check that these two symbols form a valid pair.
• If we reach the end of the expression and the stack is empty, then the original expression was
properly matched.
• Otherwise, there must be an opening delimiter on the stack without a matching symbol. If the
length of the original expression is n, the algorithm will make at most n calls to push and n calls
to pop.
FR I D AY , 1 1 O CT O BE R 2 0 24 24
How would you do it?
Character Stack
Read contents
• Delimiter Matching
( (
(a * [b – c]) / d a (
* (
[ ([
b ([
- ([
c ([
] (
)
/
d
FR I D AY , 1 1 O CT O BE R 2 0 24 25
Matching Parentheses and HTML Tags
FR I D AY , 1 1 O CT O BE R 2 0 24 27
Summary
FR I D AY , 1 1 O CT O BE R 2 0 24 28
QUEUE
FR I D AY , 1 1 O CT O BE R 2 0 24 29
Queue - Introduction
• Accessible item ?
• First inserted item
• First in, first out (FIFO)
• Tail / Head of queue
• Operations
• Insert / Enqueue
• Remove / Dequeue
• Properties
• Full
• Empty
FR I D AY , 1 1 O CT O BE R 2 0 24 30
What is a queue?
FR I D AY , 1 1 O CT O BE R 2 0 24 31
Queue info
FR I D AY , 1 1 O CT O BE R 2 0 24 32
Queue operations
FR I D AY , 1 1 O CT O BE R 2 0 24 34
Operations - Dequeue
FR I D AY , 1 1 O CT O BE R 2 0 24 35
Queue example
• enqueue(5) • dequeue()
• enqueue(3) • isEmpty()
• dequeue() • enqueue(9)
• enqueue(6) • enqueue(7)
• dequeue() • size()
• front() • enqueue(4)
• dequeue() • dequeue()
Queue example
Operation Output Queue
enqueue(5) - (5)
enqueue(3) - (5, 3)
dequeue() 5 (3)
enqueue(6) - (3, 6)
dequeue() 3 (6)
front() 6 (6)
dequeue() 6 ()
dequeue() “error” ()
isEmpty() true ()
enqueue(9) - (9)
enqueue(7) - (9, 7)
size() 2 (9, 7)
enqueue(4) - (9, 7, 4)
dequeue() 9 (7, 4)
Check queue
FR I D AY , 1 1 O CT O BE R 2 0 24 38
Efficiency of queue
• Enqueue?
• Dequeue?
• ➔ O(1)
FR I D AY , 1 1 O CT O BE R 2 0 24 39
Application
Shared
Service
Round-robin (RR) is one of the simplest scheduling algorithms for processes in an operating system, which assigns time slices to each process
in equal portions and in circular order, handling all processes without priority. Round-robin scheduling is both simple and easy to implement,
and starvation-free. Round-robin scheduling can also be applied to other scheduling problems, such as data packet scheduling in computer
networks.
The name of the algorithm comes from the round-robin principle known from other fields, where each person takes an equal share of
something in turn
Array-based Queue
wrapped-around configuration
Q
0 1 2 l f
FR I D AY , 1 1 O CT O BE R 2 0 24 42
Array-
based
Queue
FR I D AY , O CT O BE R 1 1 , 2 02 4 43
Array implementation of a queue
class ArrayQueue { private boolean grow() {
protected Object [] a; int i,j;
protected int max;
protected int first, last; int max1 = max + max/2;
return(a[first]); return(x);
} }
FR I D AY , 1 1 O CT O BE R 2 0 24 45
Queue Interface in Java
FR I D AY , 1 1 O CT O BE R 2 0 24 48
Double-Ended Queues (Deque)
• A queue-like data structure that supports insertion and deletion at both the front and
the back of the queue.
• Such a structure is called a double-ended queue, or deque, which is usually
pronounced “deck” to avoid confusion with the dequeue method of the regular queue
ADT, which is pronounced like the abbreviation “D.Q.”
• The deque abstract data type is more general than both the stack and the queue ADTs.
The extra generality can be useful in some applications.
• For example, we described a restaurant using a queue to maintain a waitlist.
Occasionally, the first person might be removed from the queue only to find that a table
was not available; typically, the restaurant will reinsert the person at the first position in
the queue. It may also be that a customer at the end of the queue may grow impatient
and leave the restaurant.
FR I D AY , 1 1 O CT O BE R 2 0 24 49
Double-Ended Queues (Deque)
• The deque abstract data type is richer than both the stack and the queue ADTs. To
provide a symmetrical abstraction, the deque ADT is defined to support the following
update methods:
• addFirst(e): Insert a new element e at the front of the deque.
• addLast(e): Insert a new element e at the back of the deque.
• removeFirst(): Remove and return the first element of the deque (or null if the deque is empty).
• removeLast(): Remove and return the last element of the deque (or null if the deque is empty).
• Additionally, the deque ADT will include the following accessors:
• first(): Returns the first element of the deque, without removing it (or null if the deque is empty).
• last(): Returns the last element of the deque, without removing it (or null if the deque is empty).
• size(): Returns the number of elements in the deque.
• isEmpty(): Returns a boolean indicating whether the deque is empty.
FR I D AY , 1 1 O CT O BE R 2 0 24 50
Priority queue
FR I D AY , 1 1 O CT O BE R 2 0 24 51
Priority queue
• Head / tail
• Enqueue / Dequeue with criteria
• E.g, dequeue
• Highest value, or
• Most severe patient, …
• Ascending-priority /
descending-priority queue
FR I D AY , 1 1 O CT O BE R 2 0 24 52
Operation
• Enqueue
• Dequeue
• Peak
FR I D AY , 1 1 O CT O BE R 2 0 24 53
Priority queue - Enqueue
FR I D AY , 1 1 O CT O BE R 2 0 24 54
Priority queue - Dequeue
FR I D AY , 1 1 O CT O BE R 2 0 24 55
Priority Queue
FR I D AY , 1 1 O CT O BE R 2 0 24 56
Efficiency of Priority queue
• Insertion ?
• If use ARRAY: O(N)
• Deletion ?
• O(1)
FR I D AY , 1 1 O CT O BE R 2 0 24 57
Array implementation of a priority queue
class PriorityQueue { public boolean isEmpty()
protected float [] a; int top, max; { return(top == -1);}
FR I D AY , 1 1 O CT O BE R 2 0 24 58
Array implementation of a priority queue
FR I D AY , 1 1 O CT O BE R 2 0 24 59
Question
FR I D AY , 1 1 O CT O BE R 2 0 24 60
Questions
FR I D AY , 1 1 O CT O BE R 2 0 24 61
Questions
Suppose you have a stack containing the elements [10, 20, 30, 40,
50], and you perform the following operations in sequence:
push(60), pop(), push(70), push(80), and pop(). What will be the
content of the stack after these operations?
• a) [10, 20, 30, 40, 50]
• b) [10, 20, 30, 40, 50, 60, 70]
• c) [10, 20, 30, 40, 70]
• d) [10, 20, 30, 40, 50, 70]
FR I D AY , 1 1 O CT O BE R 2 0 24 62
Questions
FR I D AY , 1 1 O CT O BE R 2 0 24 63
Questions
Suppose you have a queue containing the elements [10, 20, 30, 40,
50], and you perform the following operations in sequence:
enqueue(60), dequeue(), enqueue(70), enqueue(80), and dequeue().
What will be the content of the queue after these operations?
a) [10, 20, 30, 40, 50]
b) [20, 30, 40, 50, 60, 70, 80]
c) [30, 40, 50, 60, 70, 80]
d) [50, 60, 70, 80]
FR I D AY , 1 1 O CT O BE R 2 0 24 64
Summary
• A queue is a waiting line that grows by adding elements to its end and shrinks
by taking elements from its front.
• A queue is a FIFO structure: First in / First out.
• In queuing theory, various scenarios are analysed, and models are built that use
queues for processing requests or other information in a predetermined
sequence (order).
• A priority queue can be assigned to enable a particular process, or event, to be
executed out of sequence without affecting overall system operation.
• In priority queues, elements are dequeued according to their priority and their
current queue position.
FR I D AY , 1 1 O CT O BE R 2 0 24 65
Vietnam National University of HCMC
International University
School of Computer Science and Engineering
THANK YOU