Sie sind auf Seite 1von 17

Stacks, Queues

CSE 2011
Winter 2007

January 24, 2007

Stacks: LIFO
z Insertions and deletions follow the Last-In First-Out rule
z Applications, examples:
Undo operation in a text editor
History of visited web pages
Sequence of method calls in Java

Stack ADT
z Data stored: arbitrary objects
z Operations:
push(object): inserts an element
object pop(): removes and returns the last
inserted element
z Other useful operations:
object top(): returns the last inserted element
without removing it
3

Error Conditions
z
z
z
z

push(object)
object pop()
object top()
Exceptions are thrown when an operation cannot be
executed
z Execution of pop() or top() on an empty stack
throws StackEmptyException
z Another useful operation:
boolean isEmpty(): returns true if the stack is empty;
false otherwise.
4

Stack Operations
z
z
z
z

push(object)
object pop()
object top()
boolean isEmpty()

z Still another useful operation:


int size(): returns the number of elements in the stack
z Any others?
Depending on implementation
5

Stack Interface
public interface Stack {
public int size();
public boolean isEmpty();
public Object top()
throws EmptyStackException;
public void push(Object o);
public Object pop()
throws EmptyStackException;
}
6

Array-based Implementation
z An array S of maximum size N
z A variable t that keeps track of the top element in array S
z Top element: S[t]
z Stack is empty: ?
z Number of elements in the stack: ?

Pseudo-code
Algorithm size():
return (t + 1);
Algorithm isEmpty():
return (t < 0);
Algorithm top():
if (isEmpty())
throw StackEmptyException;
return S[t];

Algorithm pop():
if (isEmpty())
throw StackEmptyException;
temp = S[t];
t = t 1;
return temp;
Optimization: set S[t] to null
before decrementing t
Homework: implement pop()
without any temp variable
8

Method push()
Algorithm push(object):
t = t + 1;
S[t] = object;

Algorithm push(object):
if (size() == N)
throw StackFullException;
t = t + 1;
S[t] = object;

z The array may become full


z push() method will then
throw a StackFullException
z Limitation of array-based
implementation

Performance of Array Implementation


z Each operation runs in O(1) time
(no loops, no recursion)
z Array-based implementation is simple, efficient,
but
z The maximum size N of the stack is fixed
z How to determine N? Not easy!
z Alternatives?
{Extendable arrays
{Linked lists (singly or doubly linked???)
10

Implementing a Stack with a Singly


Linked List
z Each node has two parts:
1. pointer to the object (data stored)
2. pointer to the next node in the list
z First node = head
z Last node = tail (next pointer is set to null)

11

pop() and push() Methods

12

Analysis of Linked List Implementation


z Space usage: O(n)
n = number of elements in the stack
z Each operation runs in O(1) time
z No limit on the stack size, subject to available memory
(run-time error OutOfMemoryError)

13

Homework and Questions


z Implement the Stack ADT using singly linked lists
z List-based and array-based operations all run in O(1)
time. List-based implementation imposes no limit on the
stack size, while array-based implementation does. Is
list-based implementation better?
z Can we perform push() and pop() at the tail of the linked
list? Analyze the running time in this case.

14

Queues
CSE 2011
Winter 2007

15

Queues: FIFO
z Insertions and removals follow the Fist-In First-Out rule:
Insertions: at the rear of the queue
Removals: at the front of the queue
z Applications, examples:
Waiting lists
Access to shared resources (e.g., printer)
Multiprogramming (UNIX)

16

Queue ADT
z Data stored: arbitrary objects
z Operations:
enqueue(object): inserts an element at the end of the
queue
object dequeue(): removes and returns the element at
the front of the queue
object front(): returns the element at the front
without removing it
z Execution of dequeue() or front() on an empty queue
throws QueueEmptyException
z Another useful operation:
boolean isEmpty(): returns true if the queue is empty;
false otherwise.
17

Queue Operations
z
z
z
z
z

enqueue(object)
object dequeue()
object front()
boolean isEmpty()
int size(): returns the
number of elements in
the queue

z Any others? Depending


on implementation and/or
applications

public interface Queue {


public int size();
public boolean isEmpty();
public Object front()
throws
QueueEmptyException;

public Object dequeue()


throws
QueueEmptyException;

public void enqueue (Object


obj);
}
18

Array-based Implementation
z An array Q of maximum size N
z Need to keep track the front and rear of the queue:
f: index of the front object
r: index immediately past the rear element
z Note: Q[r] is empty (does not store any object)

19

Array-based Implementation
z
z
z
z

Front element: Q[f]


Rear element: Q[r 1]
Queue is empty: f = r
Queue size: r f

20

10

Dequeue() and Enqueue()


Algorithm dequeue():
if (isEmpty())
throw QueueEmptyException;

temp = Q[f];
f = f + 1;
return temp;

Algorithm enqueue(object):
if (r == N)
throw QueueFullException;

Q[r] = object;
r = r + 1;

21

Circular Array Implementation

z Analogy:
A snake chases its tail
z Front element: Q[f]
Rear element: Q[r 1]

z Incrementing f, r
f = (f + 1) mod N
r = (r + 1) mod N
mod: Java operator %

22

11

Circular Array Implementation

z Queue size =
(N f + r) mod N
verify this
z Queue is empty: f = r
z When r reaches and
overlaps with f, the queue
is full: r = f

z To distinguish between
empty and full states, we
impose a constraint: Q
can hold at most N 1
objects (one cell is
wasted). So r never
overlaps with f, except
when the queue is empty.
23

Pseudo-code
Algorithm enqueue(object):
if (size() == N 1)
throw QueueFullException;

Q[r] = object;
r = (r + 1) mod N;

Algorithm dequeue():
if (isEmpty())
throw QueueEmptyException;

temp = Q[f];
f = (f + 1) mod N;
return temp;

24

12

Pseudo-code
Algorithm front():
if (isEmpty())
throw QueueEmptyException;

return Q[f];
Algorithm isEmpty():
return (f = r);
Algorithm size():
return ((N f + r) mod N);

Homework: Remove the


constraint Q can hold at
most N 1 objects. That
is, Q can store up to N
objects. Implement the
Queue ADT using a
circular array.
Note: there is no
corresponding built-in
Java class for queue ADT
25

Analysis of Circular Array Implementation


Performance
z Each operation runs in O(1) time
Limitation
z The maximum size N of the queue is fixed
z How to determine N?
z Alternatives?
{Extendable arrays
{Linked lists (singly or doubly linked???)
26

13

Singly or Doubly Linked?


z Singly linked list

z Doubly linked list

private static class Node<AnyType>


{
public AnyType data;
public Node<AnyType> next;
}

private static class Node<AnyType>


{
public AnyType data;
public Node<AnyType> prev;
public Node<AnyType> next;
}

z Needs less space.


z Simpler code in some cases.
z Insertion at tail takes O(n).

z Better running time in many


cases (discussed before).

27

Implementing a Queue with a Singly


Linked List

z Head of the list = front of the queue


z Tail of the list = rear of the queue
z Why not the opposite?
28

14

dequeue(): Removing at the Head

29

Method enqueue() in Java


public void enqueue(Object obj) {
Node node = new Node();
node.setElement(obj);
node.setNext(null); // node will be new tail node
if (size == 0)
head = node;
// special case of a previously empty queue
else
tail.setNext(node); // add node at the tail of the list
tail = node;
// update the reference to the tail node
size++;
}

30

15

enqueue(): Inserting at the Tail

31

Method dequeue() in Java


public Object dequeue() throws QueueEmptyException {
Object obj;
if (size == 0)
throw new QueueEmptyException("Queue is empty.");
obj = head.getElement();
head = head.getNext();
size;
if (size == 0)
tail = null; // the queue is now empty
return obj;
}

32

16

Analysis of Implementation with SinglyLinked Lists


z Each methods runs in O(1) time
z Note: Removing at the tail of a singly-linked list requires
(n) time
Comparison with array-based implementation:
z No upper bound on the size of the queue (subject to
memory availability)
z More space used per element (next pointer)
z Implementation is more complicated (pointer
manipulations)
z Method calls consume time (setNext, getNext, etc.)
33

Upcoming Topics
z The adapter design pattern
z Applications of stacks and queues
z Extendable arrays
z Iterators, listIterators
z Lower bound for sorting (after Trees)
z When to use which sorting algorithm?
z Quick sort with duplicate elements

34

17

Das könnte Ihnen auch gefallen