CSE143 Notes for Monday, 10/13/08

In computer science, two of the most fundamental collections are called stacks and queues. They are so simple that they almost seem not worth studying. They are like the programming equivalent of drawers and shelves. Drawers and shelves are very simple and, therefore, sort of boring, and yet we find uses for them everywhere we turn.

It is useful to study stacks and queues as a way to understand a minimal kind of data structure. We'll find, for example, that they are less powerful than the list structures we have been looking at. But we often find ourselves wanting to think in terms of the simplest possible solution to a problem, as in, "You could solve that with a stack."

Like lists, stacks and queues store an ordered sequence of values. A minimal set of operations for such a structure would require at least:

These three operations are the bare bones that you'd need for such a structure and in their purest form, stacks and queues have just these three operations. Java's version of these also includes a size method that lets you ask for the number of elements in the structure.

Stacks and queues are similar in that they each store a sequence of values in a particular order. But stacks are what we call LIFO structures while queues are FIFO structures:

        stacks        queues

        L-ast         F-irst
        I-n           I-n
        F-irst        F-irst
        O-ut          O-ut
The analogy for stacks is to think of a cafeteria and how trays are stacked up. When you go to get a tray, you take the one on the top of the stack. You don't bother to try to get the one on the bottom, because you'd have to move a lot of trays to get to it. Similarly if someone brings clean trays to add to the stack, they are added on the top rather than on the bottom. The result is that stacks tend to reverse things. Each new value goes to the top of the stack, and when we take them back out, we draw from the top, so they come back out in reverse order.

The analogy for queues is to think about standing in line at the grocery store. As new people arrive, they are told to go to the back of the line. When the store is ready to help another customer, the person at the front of the line is helped. In fact, the British use the word "queue" the way we use the word "line" telling people to "queue up" or to "go to the back of the queue".

In the case of a stack, the adding operation is called "push" and the removing operation is called "pop". All operations occur at one end of the stack, at the top. We push values onto the top and we pop them off the top. There is also a method for testing whether the stack is empty and an operation for requesting the current size of the stack. The Stack class has the following operations:

        public Stack() { ... }

        public void push(E value) { ... }
        public E pop() { ... }
        public E peek() { ... }
        public boolean isEmpty() { ... }
        public int size() { ... }
Notice that we are using Java generics to define the Stack in terms of an unspecified element type E. That way we'll be able to have a Stack<String> or Stack<Integer> or a Stack of any other kind of element type we are interested in.

For queues, we have a corresponding set of operations but they have different names. When values go into a queue we sometimes refer to it as "enqueueing" a value. When values are removed from a queue we sometimes refer to it as "dequeueing" a value. Queues have the following methods:

        public void add(E value) { ... }
        public E remove() { ... }
        public E peek() { ... }
        public boolean isEmpty() { ... }
        public int size() { ... }
A strange thing about queues (which we'll discuss later) is that you must write the word LinkedList after the new operator when constructing one, rather than the word Queue. This has to do with interfaces, which we'll learn later in the course. For example:
        Queue<String> q = new LinkedList<String>();
Here is a simple client program that uses an array of String data to initialize a stack and a queue and to print their contents:

        public class Mon {
            public static void main(String[] args) {
            String[] data = {"four", "score", "and", "seven", "years", "ago"};
            Queue<String> q = new LinkedList<String>();
            Stack<String> s = new Stack<String>();
            
            for (String str : data) {
                q.add(str);
                s.push(str);
            }
            
            System.out.println(q);
            while (!q.isEmpty()) {
                System.out.println(q.remove());
            }
            
            System.out.println(s);
            while (!s.isEmpty()) {
                System.out.println(s.pop());
            }
        }
It produces the following output:

        [four, score, and, seven, years, ago]
        four
        score
        and
        seven
        years
        ago
        [four, score, and, seven, years, ago]
        ago
        years
        seven
        and
        score
        four
I said that we would continue the discussion of stacks and queues in Wednesday's lecure.


Stuart Reges
Last modified: Wed Oct 29 21:45:57 PDT 2008