Docstoc

Stacks_ Queues

Document Sample
Stacks_ Queues Powered By Docstoc
					                                Stacks, Queues
                                               CSE 2011
                                              Winter 2007



January 24, 2007                                                  1




Stacks: LIFO
     Insertions and deletions follow the Last-In First-Out rule

     Applications, examples:
      – Undo operation in a text editor
      – History of visited web pages
      – Sequence of method calls in Java




                                                                  2




                                                                      1
Stack ADT
 Data stored: arbitrary objects

 Operations:
 – push(object): inserts an element
 – object pop(): removes and returns the last
     inserted element

 Other useful operations:
 – object top(): returns the last inserted element
     without removing it

                                                            3




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




                                                                2
Stack Operations
  push(object)
  object pop()
  object top()
  boolean isEmpty()

  Still another useful operation:
  int size(): returns the number of elements in the stack

  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




                                                                3
Array-based Implementation
  An array S of maximum size N
  A variable t that keeps track of the top element in array S

  Top element: S[t]
  Stack is empty: ?
  Number of elements in the stack: ?




                                                                7




Pseudo-code
Algorithm size():              Algorithm pop():
 return (t + 1);                if (isEmpty())
                                 throw StackEmptyException;
Algorithm isEmpty():            temp = S[t];
 return (t < 0);                t = t – 1;
                                return temp;
Algorithm top():
 if (isEmpty())                Optimization: set S[t] to null
  throw StackEmptyException;     before decrementing t
 return S[t];                  Homework: implement pop()
                                 without any temp variable

                                                                8




                                                                    4
Method push()
Algorithm push(object):         Algorithm push(object):
 t = t + 1;                      if (size() == N)
S[t] = object;                    throw StackFullException;
                                 t = t + 1;
                                S[t] = object;
  The array may become full
  push() method will then
  throw a StackFullException
  Limitation of array-based
  implementation



                                                              9




Performance of Array Implementation
  Each operation runs in O(1) time
  (no loops, no recursion)
  Array-based implementation is simple, efficient,
  but …
  The maximum size N of the stack is fixed
  How to determine N? Not easy!

  Alternatives?
     Extendable arrays
     Linked lists (singly or doubly linked???)
                                                              10




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




                                                  11




pop() and push() Methods




                                                  12




                                                       6
Analysis of Linked List Implementation


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




                                                             13




Homework and Questions
 Implement the Stack ADT using singly linked lists

 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?

 Can we perform push() and pop() at the tail of the linked
 list? Analyze the running time in this case.



                                                             14




                                                                  7
                                           Queues
                                          CSE 2011
                                         Winter 2007



                                                              15




Queues: FIFO
 Insertions and removals follow the Fist-In First-Out rule:
 – Insertions: at the rear of the queue
 – Removals: at the front of the queue

 Applications, examples:
 – Waiting lists
 – Access to shared resources (e.g., printer)
 – Multiprogramming (UNIX)



                                                              16




                                                                   8
Queue ADT
 Data stored: arbitrary objects
 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
 Execution of dequeue() or front() on an empty queue
 → throws QueueEmptyException
 Another useful operation:
 – boolean isEmpty(): returns true if the queue is empty;
     false otherwise.
                                                         17




Queue Operations
 enqueue(object)             public interface Queue {
 object dequeue()            public int size();
 object front()              public boolean isEmpty();
 boolean isEmpty()           public Object front()
                              throws
 int size(): returns the       QueueEmptyException;
 number of elements in       public Object dequeue()
 the queue
                              throws
                               QueueEmptyException;
 Any others? Depending       public void enqueue (Object
 on implementation and/or      obj);
 applications                }

                                                         18




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




                                                       19




Array-based Implementation
 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():         Algorithm enqueue(object):
if (isEmpty())               if (r == N)
throw QueueEmptyException;    throw QueueFullException;
temp = Q[f];                 Q[r] = object;
f = f + 1;                   r = r + 1;
return temp;




                                                          21




Circular Array Implementation




  Analogy:                     Incrementing f, r
  A snake chases its tail      f = (f + 1) mod N
                               r = (r + 1) mod N
  Front element: Q[f]          mod: Java operator “%”
  Rear element: Q[r – 1]


                                                          22




                                                               11
Circular Array Implementation




  Queue size =                   To distinguish between
  (N – f + r) mod N              empty and full states, we
  → verify this                  impose a constraint: Q
                                 can hold at most N – 1
  Queue is empty: f = r          objects (one cell is
  When r reaches and             wasted). So r never
  overlaps with f, the queue     overlaps with f, except
  is full: r = f                 when the queue is empty.

                                                         23




Pseudo-code
Algorithm enqueue(object):     Algorithm dequeue():
if (size() == N – 1)           if (isEmpty())
 throw QueueFullException;     throw QueueEmptyException;
Q[r] = object;                 temp = Q[f];
r = (r + 1) mod N;             f = (f + 1) mod N;
                               return temp;




                                                         24




                                                              12
Pseudo-code
Algorithm front():               Homework: Remove the
if (isEmpty())                     constraint “Q can hold at
throw QueueEmptyException;
                                   most N – 1 objects”. That
                                   is, Q can store up to N
return Q[f];                       objects. Implement the
                                   Queue ADT using a
Algorithm isEmpty():               circular array.
 return (f = r);
                                 Note: there is no
Algorithm size():                  corresponding built-in
 return ((N – f + r) mod N);       Java class for queue ADT

                                                           25




Analysis of Circular Array Implementation

Performance
  Each operation runs in O(1) time

Limitation
  The maximum size N of the queue is fixed
  How to determine N?
  Alternatives?
      Extendable arrays
      Linked lists (singly or doubly linked???)
                                                           26




                                                                13
Singly or Doubly Linked?
   Singly linked list                   Doubly linked list
                                     private static class Node<AnyType>
private static class Node<AnyType>
                                        {
   {
                                          public AnyType data;
     public AnyType data;
                                          public Node<AnyType> prev;
     public Node<AnyType> next;
                                          public Node<AnyType> next;
   }
                                        }

   Needs less space.                    Better running time in many
   Simpler code in some cases.          cases (discussed before).
   Insertion at tail takes O(n).


                                                                          27




Implementing a Queue with a Singly
Linked List




   Head of the list = front of the queue
   Tail of the list = rear of the queue
   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 Singly-
Linked Lists
  Each methods runs in O(1) time
  Note: Removing at the tail of a singly-linked list requires
  θ(n) time

Comparison with array-based implementation:
  No upper bound on the size of the queue (subject to
  memory availability)
  More space used per element (next pointer)
  Implementation is more complicated (pointer
  manipulations)
  Method calls consume time (setNext, getNext, etc.)

                                                                33




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


                                                                34




                                                                     17

				
DOCUMENT INFO