View page as slide show

Click presentation screen icon to the right to see the slide show.

Chapters 7 and 8: Stacks and Queues

Data structures built for particular, common, patterns of accessing elements.

  • Stacks: last-in, first-out
    • always get most recently added, or youngest, item
    • great for dealing with mathematical expressions, processing sentences in languages, sorting algorithms, nest function calls, and much more
  • Queues: first-in, first-out
    • always get oldest item
    • great for dealing with buffer of things that need servicing where you want to service the oldest one first

7.1 The ADT Stack

From the user's side of the wall, how do you want to use a stack?

  • Add something to the stack.
  • Get and remove the most recently added item.
  • Examine what the most recently added item.
  • Check to see if it is empty.

That's it. Prevent user from seeing or removing any other items. Always add, examine, and remove from the “top” of the stack.

7.1 The ADT Stack

Stack<String> stack = new Stack<String>();

To add is to “push” onto the top of the stack.

stack.push("something");  
stack.push("hello");

To examine is to “peek” at the top of the stack.

String top = stack.peek();  // top is "hello"

To remove is to “pop” from the top of the stack.

String top = stack.pop();  // top is now "hello"
String top = stack.pop();  // top is now "something"

To see if it is empty,

boolean empty = stack.isEmpty();

An axiom of a stack is, a push followed by a pop does not change the stack.

stack.push(newItem).pop() = stack

7.3 User Side of Wall

Let's formalize our view of the Stack using a java interface.

public interface StackInterface {
 
 ... What goes in here? ...
 
}

7.3 User Side of Wall

Let's formalize our view of the Stack using a java interface.

public interface StackInterface {
 
 ... What goes in here? ...
 
 ... Right.  Only constants and abstract methods. ...
 
}

7.3 User Side of Wall

StackInterface.java
public interface StackInterface<T> {
 
    public boolean isEmpty();
 
    public void push(T newItem) throws StackException;
 
    public T pop() throws StackException;
 
    public T peek() throws StackException;
}

But with all of those wonderful comments on pages 363-364 which include preconditions and postconditions.

7.3 User Side of Wall

Don't forget to define the new exception class.

StackException.java
public class StackException extends java.lang.RuntimeException {
 
    public StackException(String s) {
        super(s);
    }
}

7.3 Reference-based Stack Implementation

First, let's create a stack. Let's say it will hold integers.

Stack<Integer> stack = new Stack<Integer>();




public class Stack<T> implements StackInterface<T> {
 
    Node<T> top;
    int size;
 
    public Stack() {
        top = null;
        size = 0;
    }
}

7.3 Reference-based Stack Implementation

Now, try pushing something on the stack.

stack.push(42);

How would you implement this?

7.3 Reference-based Stack Implementation

Now, try pushing something on the stack.

stack.push(42);

How would you implement this?

public class Stack<T> implements StackInterface<T> {
    .
    .
    .
    public void push(T newItem) {
 
        Node<T> newNode = new Node<T>(newItem, top);
        top = newNode;
        size++;
 
    }
}

7.3 Reference-based Stack Implementation

Now, what if we push again?

stack.push(62);

What will the linked list look like?

7.3 Reference-based Stack Implementation

Now, what if we push again?

stack.push(62);

What will the linked list look like?

7.3 Reference-based Stack Implementation

And now, pop the top.

int top = stack.pop();

What will the list look like?

7.3 Reference-based Stack Implementation

And now, pop the top.

int top = stack.pop();

What will the list look like?

7.3 Reference-based Stack Implementation

And now, pop the top.

int top = stack.pop();

What will the list look like?

And how would you implement it?

7.3 Reference-based Stack Implementation

And now, pop the top.

int top = stack.pop();

What will the list look like?

And how would you implement it?

public class Stack<T> implements StackInterface<T> {
    .
    .
    .
    public T pop() {
 
        Node<T> oldTop = top;
        top = top.next;
        size--;
        return oldTop.item;
 
    }
}

7.3 Reference-based Stack Implementation

What about peeking at the top?

int top = stack.peek();

And how would you implement it?

7.3 Reference-based Stack Implementation

What about peeking at the top?

int top = stack.peek();

And how would you implement it?

public class Stack<T> implements StackInterface<T> {
    .
    .
    .
    public T peek() {
 
        return top.item;
 
    }
}

7.3 Reference-based Stack Implementation

But what about throwing exceptions, using our brand-new StackException class?

public class Stack<T> implements StackInterface<T> {
    .
    .
    .
    public T pop() throws StackException {
        if (!isEmpty()) {
 
            Node<T> oldTop = top;
            top = top.next;
            size--;
            return oldTop.item;
 
        } else {
            throw new StackException("StackException: pop() attempt on empty stack");
        }
    }
 
    public T peek() throws StackException {
 
        if (!isEmpty()) {
 
            return top.item;
 
        } else {
            throw new StackException("StackException: peek() attempt on empty stack");
        }
    }
 
    public boolean isEmpty() {
        return top == null;   // or size == 0
    }
}

Little Review of Interfaces

Purposes:

  • User and implementor work independently and write correct code. Both can compile with the Interface.java file to check their code before other is finished.
  • Advanced: Variable can be defined of the interface type. Constructor can decide which class that implements the interface to use.
public interface ListInterface<T> {     . . .    }
 
public class ListArray<T> implements ListInterface<T> {   . . .   }
 
public class ListReferences<T> implements ListInterface<T> {   . . .   }
 
public class Stack<T> {
 
   protected ListInterface<T> list;  // list can be instance of any
                                     //   class that implements ListInterface<T>
 
   public Stack(String kindOf) {  // Stack<Integer> s = new Stack<Integer>("array");
                                  // Stack<Integer> s = new Stack<Integer>("references");
      if (kindOf.equals("array")) {
         list = new ListArray<T>();
 
      } else if (kindOf.equals("references")) {
         list = new ListReferences<T>();
 
      } else {
         throw java.lang.RuntimeException("Stack constructor: argument " + kindOf + 
            " not recognized.");
      }
   }
 
   . . .
}

Little Review of Interfaces

Related to first assignment…

A parameterized type in one class can be “passed” to another class.

public class A<T> {
 
    protected B<T> aBobject;
 
    public A() {
 
        aBobject = new B<T>();
    }
}
 
public class B<T> {
 
    protected T item;
 
    public B(T itemArg) {
 
        item = itemArg;
    }
}

7.2, 7.4 Applications of Stack

Recognize whether a string is in the language

Algorithm:

  1. Create a stack to hold characters.
  2. Push onto the stack each character in until '-' seen.
  3. For each remaining character, pop one of stack and compare.
    1. If not equal or stack is empty, stop with answer “No, not in L”.
  4. If end of string reached and stack is empty, stop with answer “Yes, in L”.
  5. If end of string reached and stack is not empty, stop with answer “No, not in L”.

7.2, 7.4 Applications of Stack

Evaluating a postfix expression is easy with a stack.

The expression is in postfix notation.

Algorithm:

  1. Create a stack to hold numbers.
  2. For each token in the postfix expression:
    1. If not an operator, push value onto stack.
    2. If an operator,
      1. Pop to get the operator op.
      2. Pop to get operand a.
      3. Pop to get operand b.
      4. Push result of (b op a).

8.1 ADT Queue

Differences from stack:

  • Adding happens at end of list.
  • Adding called enqueue rather than push
  • Removing called dequeue rather than pop

8.3 User Side of Wall

QueueInterface.java
public interface QueueInterface<T> {
 
    public boolean isEmpty();
 
    public void enqueue(T newItem) throws QueueException;
 
    public T dequeue() throws QueueException;
 
    public T peek() throws QueueException;
}
QueueException.java
public class QueueException extends java.lang.RuntimeException {
 
    public QueueException(String s) {
        super(s);
    }
}

8.3 Reference-based Queue Implementation

First, let's create a queue. Let's say it will hold integers.

Queue<Integer> queue = new Queue<Integer>();




public class Queue<T> implements QueueInterface<T> {
 
    Node<T> lastNode;
    int size;
 
    public Queue() {
        lastNode = null;
        size = 0;
    }
}

8.3 Reference-based Queue Implementation

Now, try adding something on the queue.

queue.enqueue(42);

How would you implement this?

8.3 Reference-based Queue Implementation

Now, try pushing something on the queue.

queue.enqueue(42);

How would you implement this?

public class Queue<T> implements QueueInterface<T> {
   .
   .
   .
    public void enqueue(T newItem) {
 
        Node<T> newNode = new Node<T>(newItem, null);
        if (isEmpty()) {
            newNode.next = newNode; // points to itself
        } else {
            newNode.next = lastNode.next;
            lastNode.next = newNode;
        }
        lastNode = newNode;
        size++;
    }
}

8.3 Reference-based Queue Implementation

Now, what if we enqueue again?

queue.enqueue(62);

What will the linked list look like?

8.3 Reference-based Queue Implementation

Now, what if we enqueue again?

queue.enqueue(62);

What will the linked list look like?

8.3 Reference-based Queue Implementation

And now, dequeue from the front.

int top = queue.dequeue();

What will the list look like?

8.3 Reference-based Queue Implementation

And now, dequeue the top.

int top = queue.dequeue();

What will the list look like?

8.3 Reference-based Queue Implementation

And now, dequeue the top.

int top = queue.dequeue();

What will the list look like?

And how would you implement it?

8.3 Reference-based Queue Implementation

And how would you implement it?

public class Queue<T> implements QueueInterface<T> {
    .
    .
    .
    public T dequeue() {
 
        Node<T> firstNode = lastNode.next;
        if (firstNode == lastNode) { // just one item in queue
            lastNode = null;
        } else {
            lastNode.next = firstNode.next;
        }
        size--;
        return firstNode.item;
 
    }
}

8.3 Reference-based Queue Implementation

What about peeking at the front?

int top = queue.peek();

And how would you implement it?

8.3 Reference-based Queue Implementation

What about peeking at the front?

int top = queue.peek();

And how would you implement it?

public class Queue<T> implements QueueInterface<T> {
    .
    .
    .
    public T peek() {
 
        return lastNode.next.item;
 
    }
}

8.3 Reference-based Queue Implementation

But what about throwing exceptions, using our brand-new QueueException class?

In dequeue and peek check for empty queue just as we did for pop and peek for the stack.

8.2, 8.4 Applications of Queue

Buffer of items. Enqueue them as acquired, dequeue them to use.

Palindromes, like “abccba”.

  • Create a stack and a queue.
  • For each character, queue.enqueue and stack.push it.
  • Now compare stack.pop() and queue.dequeue().
    • If not equal, stop with answer “No, not a palindrome”.
  • If stack and queue become empty, stop with answer “Yes, a palindrome”.

Event-based simulation.

Additional Chapter 8 Material

Array-based implementation of queue. Circular array.

Deque (“deck”), a double ended queue.

Recent changes RSS feed CC Attribution-Share Alike 3.0 Unported Driven by DokuWiki