Download Stacks, Queues, and Deques STACKS The Stack Abstract Data

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts
no text concepts found
Transcript
STACKS
• 
Stacks, Queues, and Deques
• 
ACS-2947 Lecture 4
• 
The Stack Abstract Data Type • 
The Stack ADT stores arbitrary objects
• 
• 
push(e): inserts an element
• 
pop( ): removes and returns the last inserted element
E.g. •  Web browsers’ recently visited sites
•  The “undo” feature of text editors
Stack Interface in Java
• 
Main stack operations:
• 
A stack is a collection of objects that are inserted
and removed according to the last-in, first-out
(LIFO) principle. A user may insert objects into a stack at any time,
but may only access or remove the most recently
inserted object that remains (the “top” of the stack). Java interface
corresponding to our Stack
ADT
• 
Assumes null is returned
from top( ) and pop( )
when stack is empty
• 
Different from the built-in
Java class
java.util.Stack
Auxiliary stack operations:
• 
object top( ): returns the last inserted element without
removing it
• 
integer size( ): returns the number of elements stored
• 
boolean isEmpty( ): indicates whether no element is
stored
Example
8
6
9
7
public interface Stack<E>{
int size( );
boolean isEmpty( );
E top( );
void push (E element);
E pop( );
}
A Stack Interface for Java
• 
Because of its importance, the stack data structure
is included as a "built-in" class in the java.util
package of Java. • 
We construct our own Stack ADT
• 
Differences:
If stack is empty:
returns null
throws exception
1
Simple Array-Based Stack Implementation
Simple Array-Based Stack Implementation
N-1
.
.
.
t
2
1
0
8
6
9
7
Sample usage
"
Analyzing the Array-Based Stack Implementation
• 
Each of the stack methods executes a constant
number of statements involving arithmetic
operations, comparisons, and assignments. • 
pop also calls isEmpty, which itself runs in constant
time
à in this implementation of the stack ADT, each
method runs in constant time, or O(1) time. Garbage Collection in Java
• 
In the pop method we set a local variable, answer, to
reference the element that is being popped, and then we
intentionally reset data[t] to null at line 22, before
decrementing t. • 
Assists is Java’s garbage collection mechanism, which
searches memory for objects that are no longer actively
referenced and reclaims their space for future use. 2
Drawback of Array-Based Stack
Implementing a Stack with a Singly Linked List
• 
Must assume a fixed upper bound, CAPACITY, on
the ultimate size of the stack. • 
Good for cases with a good estimate on the
number of items needed to go into the stack
• 
The linked-list approach has a memory usage that
is always proportional to the number of actual
elements currently in the stack
• 
We use the adapter design pattern
• 
• 
Stacks serve a vital role in a number of computing
applications, so it is helpful to have a fast stack
ADT implementation such as the simple arraybased implementation. The Adapter Pattern
• 
• 
Implementing a Stack with a Singly Linked List
Define a new class that contains an instance of the
existing class as a hidden field
• 
Applies to any context where we effectively want to
modify an existing class so that its methods match
those of a related, but different, class of interface
Then implement each method of the new class
using methods of this hidden instance variable. Creates a new class that performs some of the
same functions as an existing class, but
repackaged in a more convenient way. • 
In the context of the stack ADT, we can adapt our
SinglyLinkedList class to define a new LinkedStack
class
• 
Declares a SinglyLinkedList named list as a private
field, and uses the following correspondences: Implementing a Stack with a Singly Linked List
head
8
6
9
7
Recall:
8
6
9
7
3
Reversing an Array with a Stack
• 
A stack can be used as a general tool to reverse a
data sequence. • 
Create an empty stack for auxiliary storage, push all
of the array elements onto the stack, and then pop
those elements off of the stack while overwriting the
cells of the array from beginning to end. Reversing an Array Using a Stack
D
C
B
A
a
D
C
B
A
buffer
A
B
C
D
a
Parentheses Matching
• 
Each opening symbol
must match its
corresponding closing
symbol
E.g.
• 
correct: ( )(( )){([( )])} • 
correct: ((( )(( )){([( )])}
• 
Parentheses: “(” and “)” • 
incorrect: )(( )){([( )])} • 
Braces: “{” and “}”
• 
incorrect: ({[ ])}
• 
Brackets: “[” and “]” • 
incorrect: ( HTML Tag Matching
• 
For fully-correct HTML, each <name> should pair
with a matching </name>
4
QUEUES
• 
A queue is a close "cousin" of the stack, as a queue is
a collection of objects that are inserted and removed
according to the first-in first-out (FIFO) principle. • 
• 
E.g. • 
• 
• 
The Queue Abstract Data Type
• 
The Queue ADT stores arbitrary objects
• 
• 
Main queue operations:
• 
enqueue(e): inserts elements at the end of the queue
• 
object dequeue( ): removes and returns the element
at the front of the queue
object first( ): returns the element at the front without
removing it
• 
integer size( ): returns the number of elements stored
• 
boolean isEmpty( ): indicates whether no elements are
stored
A Queue Interface for Java
• 
• 
handling calls in a customer service centre
web server responding to requests
networked printer
Queue Interface in Java
• 
Java interface
corresponding to our Queue
ADT
• 
Assumes null is returned
from first( ) and
dequeue( ) when stack
is empty
• 
java.util.Stack supports
two styles for most
operations
Auxiliary queue operations
• 
Elements can be inserted at any time, but only the
element that has been in the queue the longest can be
removed at any time. public interface Queue<E>{
int size( );
boolean isEmpty( );
void enqueue (E e);
E first( );
E dequeue( );
}
Example
The queue data structure is also included as a
"built-in" class in the java.util package of Java. We construct our own Queue ADT
• 
Differences:
4
9
7
5
Array-Based Queue Implementation
Array-Based Queue Implementation
Avoid the loop
B. 
• 
How to implement the dequeue operation?
• 
Replace an element in the array with a null reference
• 
Maintain an explicit variable f to represent the index of the
element that is currently at the front of the queue
• 
Would run in O(1) time
Execute a loop to shift all other elements of the
queue one cell to the left to align front with cell 0
A. 
• 
N O P
Q R
Results in a O(n) running time
• 
Eventually the back of the queue would reach the end of
the underlying array Array-Based Queue Implementation
Use an Array Circularly
C. 
.
..
P
G
F
L M
• 
N
O
f
r
P
N-1
Q
0
R
1
• 
Use an array of size N in a circular fashion • 
• 
Queue Operations
We use the modulo operator (remainder in division)
• 
• 
• 
E.g. 1%5 = 1, 2%5 = 2, 5%5 = 0, 8%5 = 3 To “advance” the front index, use Two variables keep track of the front and rear f index of the front element
•  r index immediately past the rear element • 
2
• 
Like B., but the contents of the queue wrap around the end
of an array as necessary
Array location r is kept empty Example
avail = (f + sz) % data.length;
(0+2) % 6 = 2
f=0
sz = 3
E.g. N = 10, f = 7
2
• 
(8 + 1) % 10 = 9
• 
(9 + 1) % 10 = 0 à wraps around
q.enqueue(7)
4
3
(7 + 1) % 10 = 8
q.enqueue(5)
q.enqueue(3)
5
f = (f + 1) % N
• 
ArrayQueue q = new ArrayQueue(5);
1
0
q.enqueue(9)
q.enqueue(4)
7
3
5
q.dequeue()
q.dequeue()
q.enqueue(2)
q.enqueue(8)
6
Example
Example
f = (f + 1) % data.length;
(0+1) % 6 = 1
f=1
sz = 4
ArrayQueue q = new ArrayQueue(5);
q.enqueue(5)
avail = (f + sz) % data.length;
(2+4) % 6 = 0
q.enqueue(3)
5
4
3
2
1
0
f=2
sz = 5
q.enqueue(7)
4
9
7
3
5
q.enqueue(9)
4
q.enqueue(4)
3
q.dequeue()
2
q.dequeue()
2
4
9
7
0
q.enqueue(8)
q.enqueue(5)
q.enqueue(3)
q.enqueue(7)
q.enqueue(9)
q.enqueue(4)
q.dequeue()
q.dequeue()
1
q.enqueue(2)
ArrayQueue q = new ArrayQueue(5);
8
q.enqueue(2)
q.enqueue(8)
Analysis
A. 
Loop to shift elements results in O(n)
B. 
Limited by array size
C. 
Each of the queue methods executes a constant
number of statements
7
Implementing a Queue with a Linked List
• 
Adapt a singly linked list to implement the queue
ADT • 
Natural orientation to align the front of the queue
with the head of the list and the back of the queue
with the tail
• 
head
5
3
7
9
Remove from the head and insert at the tail
Recall:
9
7
3
5
Analyzing the Efficiency of a Linked Queue • 
Each method of the LinkedStack class runs in O(1)
time. Therefore, each method of our LinkedQueue
adaptation also runs in O(1)time. • 
We also avoid the need to specify a maximum size
for the queue, as was done in the array-based
queue implementation. • 
Analyzing the Efficiency of a Linked Queue • 
Although all methods execute in constant time for both
implementations, the operations involving linked lists
have a large number of primitive operations per call. • 
• 
For example, adding an element to an array-based
queue consists primarily of calculating an index with
modular arithmetic, storing the element in the array cell,
and incrementing the size counter. For a linked list, an insertion includes the instantiation
and initialization of a new node, relinking an existing
node to the new node, and incrementing the size
counter. Because each node stores a next reference, in
addition to the element reference, a linked list uses
more space per element than a properly sized array
of references. DEQUES: Double-Ended Queues
• 
Supports adding at front and back of the line as
well as removing from front and back of the line
• 
E.g. Restaurant waitlist
• 
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. 8
The Deque Abstract Data Type
• 
• 
Main queue operations:
• 
AddFirst(e): inserts elements at the front of the deque
• 
AddLast(e): inserts elements at the end of the deque
• 
removeFirst( ): removes and returns the first element of the deque
• 
removeLast( ): removes and returns the last element of the deque
Deque Interface in Java
• 
Java interface
corresponding to our
Deque ADT
• 
Auxiliary deque operations
• 
object first( ): returns the first element without removing it
• 
object last( ): returns the last element without removing it
• 
integer size( ): returns the number of elements stored
• 
boolean isEmpty( ): indicates whether no elements are stored
Example
Implementing a Deque
• 
6
8
6
Assumes null is
returned from first( )
and last( ) when deque
is empty
public interface Deque<E>{
int size( );
boolean isEmpty( );
E first( );
E last( );
void addFirst (E e);
void addLast (E e);
E removeFirst( );
E removeLast( );
}
Since the deque requires insertion and removal at
both ends of a list, using a singly linked list to
implement a deque would be inefficient. • 
Use a doubly linked list to implement a deque
efficiently. • 
Inserting or removing elements at either end of a
doubly linked list is straightforward to do in O(1) time
• 
use sentinel nodes for the header and trailer
9