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 firstcome, 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 registers. At present the stack is empty.

We push two pairs of shoes sneakers Westcos

We push three more pairs – the stack is now full Moccasins 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 Shoe firstPair = shoeStack.pop(); Riding boots Flip-Flops sneakers Westcos // Riding Boots Shoe secondPair = shoeStack.pop(); Flip-Flops sneakers Westcos // Ahhh.... just right Shoe toWearNow = shoeStack.pop(); sneakers 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 shoeStack.push(secondPair); Riding boots sneakers Westcos // Moccasins shoeStack.push(firstPair); Moccasins Riding boots 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 Shoe wearingNow = fromFeet(); shoeStack.push(wearingNow); Flip-Flops Moccasins Riding boots sneakers Westcos

// the new pair Shoe newPair = new dressShoe(black); shoeStack.push(newPair); Chic Flip-Flops Moccasins Riding boots 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) Pop() Clear() puts x at the TOP, moves contents of other registers down returns value of the TOP register, moves lower registers up one 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() IsFull() returns true if and only if all registers are empty 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())

Master your semester with Scribd & The New York Times

Special offer for students: Only $4.99/month.

Master your semester with Scribd & The New York Times

Cancel anytime.