You are on page 1of 5

The Stack (I)

A classic data structure


Lest we should think for a moment that ‘classic’ means ‘old fashioned and outmoded,’
rest assured that you have been relying on a stack since you logged on.

We all know what a ‘stack’ is. Imagine a short pile of shoe boxes, one on top of another.
You could put things – shoes for example – in the boxes and pile them up, but not too
high. Of course, order matters because if the shoes you’ll want to wear next are not in the
top box, or at least one of the upper boxes, you’ll have to move all the boxes stacked on
top of the one you want before you can put your shoes on.

Pause here and make sure you understand the problem I've attempted to describe. Despite
this limitation, stacks are very useful – and fast.

LIFO in the fast lane.


Collections – in this case a sequenced container – come in different inherent orders (and
some aren’t ordered at all). A stack is a Last In, First Out structure. This just means that
the last pair of shoes is in the topmost box. You ‘push’ a new box (hopefully with shoes)
on top of the ones already there. When you want to get a pair, the only pair you can ‘pull’
from the stack are in the topmost box.

A LIFO structure is exactly the opposite of a well-behaved line at the cafeteria – a first-
come, first-served structure, otherwise known as FIFO (first-in,, first – out).

Typically stacks have a fixed size. If you try to push a box onto the top of the stack and
the stack is already full, the bottom most box disappears. It just vanishes to make room
for the new box. If it did not do this, you’d have a ‘stack crash’ – imagine the stack of
shoe boxes collapsing under its own weight, shoes flying everywhere. This is stack
overflow.

You could pull boxes, one after another (you can only push or pull one box at a time, and
only from the top of the stack), but eventually you would take off the last box. If you then
tried pointlessly to pull one more box from the empty stack, you’d have a runtime error.
In the case of Java, that probably means (yes, you guessed it) an exception! We will see if
we can do a little better, but popping an empty stack is a definite no-no called stack
underflow.
This stack has five We push two pairs of We push three more
registers. At present the shoes pairs – the stack is now
stack is empty. full

sneakers Moccasins
Westcos Riding boots
Flip-Flops
sneakers
Westcos

This is perhaps the code to get the stack in the middle column

Stack shoeStack = new Stack (5 ) ;


/ / a poss ib le cons t ruc to r ca l l
shoeStack .push (new Boots ( “Wes tco” ) ) ;
/ / add boots
shoeStack .push (new Sneake rs (Shoes .Co lo rs .BLUE) ) ;
/ / add sneakers nex t

and now we fill the stack (right column)

shoeStack .push (new F l i p _F lops ( ) ) ;


shoeStack .push (new Boots ( “ Jus t i n” ) ) ;
shoeStack .push (new Moccas ins ( ) ) ;

Now the stack is full (right hand column). The Westcos are at the bottom, the moccasins
(Last In, First Out) are on the top.

Darn. We want to wear our Flip-Flops – right now!

// Moccasins // Riding Boots // Ahhh.... just right


Shoe firstPair = Shoe secondPair = Shoe toWearNow =
shoeStack.pop(); shoeStack.pop(); shoeStack.pop();

Riding boots Flip-Flops sneakers


Flip-Flops sneakers Westcos
sneakers Westcos
Westcos
You can see that we need to assign the return value from Pop() to some reference, or
we’ll lose those shoes forever. We need an l-value unless we want the shoes to disappear.
Of course we don’t want to leave a bunch shoes laying around before we go, so let’s put
back the one’s we won’t be wearing:

// Riding Boots // Moccasins


shoeStack.push(secondPair); shoeStack.push(firstPair);

Riding boots Moccasins


sneakers Riding boots
Westcos sneakers
Westcos

Note the last-out, first-in approach. Forgetting about the Flip-Flops on our feet, we Push
the Boots in first because (prior to the Flip-Flops) they were the last one’s out.

So let’s say that on the way back from the beach we found these really chic dress shoes
on sale. Since we’ll want to show these off when we next go out, we’ll put them at the top
of the stack (that is, push them last).

// Flip-Flops // the new pair


Shoe wearingNow = fromFeet(); Shoe newPair = new dressShoe(black);
shoeStack.push(wearingNow); shoeStack.push(newPair);

Flip-Flops Chic
Moccasins Flip-Flops
Riding boots Moccasins
sneakers Riding boots
Westcos sneakers

Oh no! We just lost our Westcos, a lovely pair, nicely broken-in and rather pricey too.
This is not so good. That’s what happens if you overfill your stack – you just lose the
contents of the bottom register. Unless the stack programmer was in a really vicious
mood, in which case your stack just overflowed and a crash is the most likely outcome.

Notice that if you look at the stack state just after we put away the Flip-Flops (and before
adding the new chic pair) we have effectively re-ordered the stack from where we had it
at the beginning. To move the Flip-Flops from the middle to the top, you have to pull
three pairs, put two back, and finally put back the entry you want on top.
Stacks are not intended to handle a lot of re-ordering. This is quite different from more
random-access containers (like lists, for example).

EXER: Sketch some code that will let you keep those Westcos before you push the
dress shoes in the shoe closet. This will take a little work, but believe me, for those boots
it’s worth it.
Please e-mail this EXER (richard.bryan@sduhsd.net). Place in the Subject line
CS .AB Stack1 f i r s t l as t
// where first is your first name and last is your last name

Individual assignment (10 pts) – Due in two days


marked on general correctness.

Review
A stack is a LIFO (last – in, first – out) data structure. Usually a stack has some fixed
size, like basic Java arrays. The topmost register is the top of the stack; the last register is
the bottom.

Full stack (six registers)


3.141569
65535
1.618
2.71828
-1.00000000001
186000

TOP
Register 1
Register 2
Register 3
Register 4
BOTTOM
What are the basic operations on a stack?

Mutating operations (changes contents)

Push(x) puts x at the TOP, moves contents of other registers down


Pop() returns value of the TOP register, moves lower registers up one
Clear() empties the stack

Good programmers always want their variables initialized, so when ever a register is
cleared (for example because of a Pop()) they would assign values to any cells not having
one.

Q: If the stack contains JFrames, what value would you assign to empty cell (register) in
the stack?

Non-mutating operations (do not change contents)

IsEmpty() returns true if and only if all registers are empty


IsFull() return true if and only if all registers are assigned

Other non-mutating operations you might find useful could include


Capacity() returns the maximum number of values the stack can hold
Size() returns the number of filled registered
Dump() returns stack information (or you could override toString())