stacks as an abstract data type

21
Stacks as an Abstract Data Type CS1316: Representing Structure and Behavior

Upload: shel

Post on 06-Jan-2016

26 views

Category:

Documents


1 download

DESCRIPTION

Stacks as an Abstract Data Type. CS1316: Representing Structure and Behavior. Story. Stack: Another useful kind of list An example of an Abstract Data Type (ADT): We can define the methods and the behavior apart from any implementation. - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Stacks as an Abstract Data Type

Stacks as an Abstract Data Type

CS1316: Representing Structure and Behavior

Page 2: Stacks as an Abstract Data Type

Story

Stack: Another useful kind of list An example of an Abstract Data Type (ADT):

• We can define the methods and the behavior apart from any implementation.

• There are multiple implementations, some better than others.

Can use a stack to reverse a list in less time, but more space.• A classic tradeoff! Space for time.

Page 3: Stacks as an Abstract Data Type

Key idea #1: Introducing a Queue

Last-In-First-Out List• First item in the list is the last one out.

• Last one in is first one out.

I got here first!

I got here second!

I got here third!

This is the top of the stack

Page 4: Stacks as an Abstract Data Type

New items go at the top

I got here first!

I got here second!

I got here third!

This is the new top of the stack

I got here fourth!

Page 5: Stacks as an Abstract Data Type

Items only get removed from the top

I got here first!

I got here second!

I got here third!

This is the new (er, old) top of the stack

I got here fourth! And now I’m outta here!

Page 6: Stacks as an Abstract Data Type

What can we do with stacks?

push(anObject): Tack a new object onto the top of the queue

pop(): Pull the top (head) object off the queue.

peek(): Get the top of the queue, but don’t remove it from the queue.

size(): Return the size of the queue

Page 7: Stacks as an Abstract Data Type

Examplestack

Welcome to DrJava.> Stack stack = new Stack()> stack.push("This")> stack.push("is")> stack.push("a")> stack.push("test")> stack.size()4> stack.peek()"test"> stack.pop()"test"> stack.pop()"a"> stack.pop()"is"> stack.pop()"This"> stack.pop()java.util.NoSuchElementException:

Notice anything interesting about the order in and the order out?

Page 8: Stacks as an Abstract Data Type

Implementing a stack with a linked list

import java.util.LinkedList; // Need for LinkedList

public class Stack { /** Where we store the elements */ private LinkedList elements; /// Constructor //// public Stack() { elements = new LinkedList(); }

Page 9: Stacks as an Abstract Data Type

Stackmethods

//// Methods /// public void push(Object element){ // New elements go at the front elements.addFirst(element); } public Object peek(){ return elements.getFirst(); } public Object pop(){ Object toReturn = this.peek(); elements.removeFirst(); return toReturn; } public int size(){return elements.size();}

Page 10: Stacks as an Abstract Data Type

A stack is a stack, no matter what lies beneath. Our description of the stack minus the

implementation is an example of an abstract data type (ADT).• An abstract type is a description of the methods that a

data structure knows and what the methods do. We can actually write programs that use the

abstract data type without specifying the implementation. • There are actually many implementations that will

work for the given ADT.• Some are better than others.

Page 11: Stacks as an Abstract Data Type

Building a Stack from an Array/** * Implementation of a stack as an array **/public class Stack2 { private static int ARRAYSIZE = 20; /** Where we'll store our elements */ private Object[] elements;

/** Index where the top of the stack is */ private int top;

Page 12: Stacks as an Abstract Data Type

Stack2 = array + top index

/// Constructor ////

public Stack2() {

elements = new Object[ARRAYSIZE];

top = 0;

}

Page 13: Stacks as an Abstract Data Type

Stack2Methods

//// Methods /// public void push(Object element){ // New elements go at the top elements[top]=element; // then add to the top top++; if (top==ARRAYSIZE){ System.out.println("Stack overflow!"); } } public Object peek(){ if (top==0){ System.out.println("Stack empty!"); return null; } else{ return elements[top-1];} } public Object pop(){ Object toReturn = this.peek(); top--; return toReturn; } /** Size is simply the top index */ public int size(){return top;}

Page 14: Stacks as an Abstract Data Type

TestingStack2

Welcome to DrJava.> Stack2 stack = new Stack2();> stack.push("Matt")> stack.push("Katie")> stack.push("Jenny")> stack.size()3> stack.peek()"Jenny"> stack.pop()"Jenny"> stack.pop()"Katie"> stack.pop()"Matt"> stack.pop()Stack empty!null

Page 15: Stacks as an Abstract Data Type

What are stacks good for?

The algorithm for converting an equation into a tree uses a stack.

As new functions get called, position in old functions get pushed on a stack.• So you always return to the last function you

were in.

• If an error occurs, you get a stack trace.

• If your recursion goes into an infinite loop, what error do you get? Stack overflow!

Page 16: Stacks as an Abstract Data Type

A Stack Example: New Reverse

Recall our original implementation of reverse().• We go to the end of the original list to find the last().

• We then remove() it (which involves walking the list until we find the one before last())

• We then insert it at the end of the new list (via add(), which does last().insertAfter()).

All told: For each node, we walk the whole list three times.• O(n*n2)=O(n3)

Page 17: Stacks as an Abstract Data Type

Original Reverse

/** * Reverse the list starting at this, * and return the last element of the list. * The last element becomes the FIRST element * of the list, and THIS goes to null. **/ public LLNode reverse() { LLNode reversed, temp; // Handle the first node outside the loop reversed = this.last(); this.remove(reversed); while (this.getNext() != null) { temp = this.last(); this.remove(temp); reversed.add(temp); }; // Now put the head of the old list on the end of // the reversed list. reversed.add(this); // At this point, reversed // is the head of the list return reversed; }

Page 18: Stacks as an Abstract Data Type

Testing Reverse in SoundListTest() public void reverseTest(){ FileChooser.setMediaPath("D:/cs1316/MediaSources/"); Sound s = null; // For copying in sounds s = new Sound(FileChooser.getMediaPath("guzdial.wav")); SoundNode root = new SoundNode(s); s = new Sound(FileChooser.getMediaPath("is.wav")); SoundNode one = new SoundNode(s); root.last().insertAfter(one); s = new Sound(FileChooser.getMediaPath("scritch-q.wav")); SoundNode two = new SoundNode(s); root.last().insertAfter(two); s = new Sound(FileChooser.getMediaPath("clap-q.wav")); SoundNode three = new SoundNode(s); two.insertAfter(three); //root.playFromMeOn(); SoundNode reversed = (SoundNode) root.reverse2(); reversed.playFromMeOn(); }

Page 19: Stacks as an Abstract Data Type

Stack-basedReverse

/** * Reverse2: Push all the elements on * the stack, then pop all the elements * off the stack. **/ public LLNode reverse2() { LLNode reversed, current, popped; Stack stack = new Stack(); current=this; while (current != null) { stack.push(current); current = current.getNext(); } reversed = (LLNode) stack.pop(); current = reversed; while (stack.size()>0) { popped=(LLNode) stack.pop(); current.insertAfter(popped); current = popped; } return reversed; }

Page 20: Stacks as an Abstract Data Type

What’s the diff? Time

How often is each node touched in reverse2()?• Twice: Once going onto the stack, once

coming off.

• O(2*n) => O(n)

The stack-based reverse is faster than the original reverse.

Page 21: Stacks as an Abstract Data Type

What’s the diff? Space

How much space does reverse2() take?• Whatever space the stack takes.

How much additional space does reverse() take? None

Very common tradeoff: Space for time.• You can make an algorithm go faster, by using more

space.

• If you need to fit into less memory, you have to do more processing, which takes more time.