Presentation is loading. Please wait.

Presentation is loading. Please wait.

Implementing Stacks Ellen Walker CPSC 201 Data Structures Hiram College.

Similar presentations


Presentation on theme: "Implementing Stacks Ellen Walker CPSC 201 Data Structures Hiram College."— Presentation transcript:

1 Implementing Stacks Ellen Walker CPSC 201 Data Structures Hiram College

2 Operations on a Stack Create an empty stack Is the stack empty? Add a new item to the stack. (Push) Remove the item that was most recently added (Pop) Retrieve the item that was most recently added (Peek)

3 Implementing a Stack All items in the stack must be stored Only the top item needs to be accessible for retrieval Therefore a stack is a restricted form of list –Use the List interface –Use an array (as inside ArrayList) –Use linked nodes (as inside LinkedList) Java does none of these - it uses a vector (growable array) –But, to understand stacks better, we will consider the 3 options above

4 Implementing using a List //Complete code pp. 272-273 public class ListStack { private List theData; public Stack { theData = new ArrayList (); } //more methods here }

5 ArrayList Implementation Push adds to the list –Where? Why? Pop removes an item –Which one? Peek looks at the top item –Where is it? ArrayList takes care of resizing the list, details of implementations

6 Empty and Push Method Public boolean empty() { return theData.size() == 0; } public E push (E obj){ //add at end of ArrayList theData.add (obj); return (obj); }

7 Peek public E peek() { if (empty()) throw new EmptyStackException(); //top is at the end of the array return theData.get(theData.size()-1); }

8 Pop public E pop() { if (empty()) throw new EmptyStackException(); //top is at the end of the array //recall: remove returns the object removed return theData.remove(theData.size()-1); }

9 And now more detail… Pretend we don’t already have ArrayList or LinkedList, and had to implement all from scratch Why? –Understand in detail how stacks work –See the differences and tradeoffs between array and linked stacks –Appreciate how much easier it is to implement a stack than a list (either type)

10 Array Implementation Push: insert element into the array (where?) Peek: retrieve the most recently inserted element (where is it?) Pop: remove the most recently inserted element (how)? Static vs. dynamic array?

11 Array Push, Pop All stack elements go into the array (in order) Newest element is last (highest index) in the array Integer variable “top” indicates index of top Push increments top Pop decrements top –Popped elements stay in array until overwritten by new push

12 Choices for top Top points after the top element –Push: first copy, then increment –Top: A[top-1] –Pop(item): first decrement, then copy If top points at the top element –Push: first increment, then copy –Top: A[top] –Pop(item): copy item, decrement

13 Example: Top at Empty stack (top = –1) Push ‘a’, Push ‘b’, Push ‘c’ (top=2) Pop, Pop (top = 0) Push ‘z’ (top = 1) A[0]=A[1]=A[2]=A[3]=A[4]= A[0]=‘a’A[1]=‘b’A[2]=‘c’A[3]=A[4]= A[0]=‘a’A[1]=‘b’A[2]=‘c’A[3]=A[4]= A[0]=‘a’A[1]=‘z’A[2]=‘c’A[3]=A[4]=

14 Possible Errors Pop from empty stack Top of empty stack –Throw EmptyStackException Push if stack is full (CAPACITY items) –not a problem if resize is allowed (as in ArrayList) –If not, a FullStackException could be thrown

15 Class definition (data members) public class ArrayStack { // array for the stack E[ ] theData; //index of top item int topOfStack = -1;

16 Constructor and Check for Empty //Initial capacity private static final int INITIAL_CAPACITY = 10; //Construct an empty stack public ArrayStack() { theData = (E[]) new Object[INITIAL_CAPACITY]; } //Empty? public boolean empty(){ return top == -1; }

17 Push //Push an item onto the stack public E push(E obj){ if (topOfStack == theData.length-1) { reallocate(); //or could throw an exception } //++top increments first, returns new value theData[++topOfStack] = obj; return obj }

18 Pop //Pop an item from a stack and return it public E Pop(){ if (empty()) throw new EmptyStackException(); else return theData[topOfStack--]; }

19 Efficiency of stack Push: constant time –Even though insert into array is not! (why?) Pop: constant time –Even though delete from array is not!

20 Node (Linked-List) Implementation Push: insert element into the list (where?) Peek: retrieve the most recently inserted element (where is it?) Pop: remove the most recently inserted element (how)? isEmpty: (how do you know the stack is empty?) What special cases require exceptions?

21 Linked implementation Underlying data structure is a singly linked list Push inserts at the beginning of the list –Exception: cannot allocate a new node Pop removes from the beginning of the list –Exception: empty list (stack) Empty stack when top is null

22 Example (Linked Implementation) Empty stack Push ‘a’, Push ‘b’, Push ‘c’ Pop, Pop Push ‘z’ cba a za

23 Class Definition Public class LinkedStack { private Node topOfStackRef = null; … private static class Node { //same as for linked list } };

24 empty & peek //Is the stack empty? Public boolean empty() { return (topOfStackRef == null); } //Get item from top Public E peek() { if (empty()) throw new EmptyStackException(); return topOfStackRef.data; }

25 Push // push (add to beginning of list) public E push (E obj){ topOfStackRef = new Node (obj, topOfStackRef); return obj; }

26 Pop //Pop and recover old top item Public E pop(){ if (empty()) throw new EmptyStackException(); else{ E result = topOfStackRef.data; topOfStackRef = topOfStackRef.next; return result; }

27 Nodes vs. Arrays Array is simpler, requires extra space (unused capacity) Node uses minimum amount of space Push and pop are O(1) either way We never need to access the middle of the list. Note: replace ArrayList by LinkedList on slide 6 to get the list functionality without writing any new code. You must also replace add() by addFirst() in push, and remove() by removeFirst() in pop.

28 Postfix Expressions Also called RPN (reverse Polish notation) –Enter first operand, then second operand, then operator –(Operands can be recursive expressions) –Example 1+(2*3) becomes 1 2 3 * + First operand is 1 Second operand is (recursively) 2 3 * Operator is +

29 Stacks Evaluate Postfix Reading the data: If you see an operand (number), push it If you see an operator, pop the first two items off the stack perform the operation push the result back on the stack Example: 1 2 3 * + –Push 1, push 2, push 3, pop 3, pop 2, push 6 –Pop 6, pop 1, push 7

30 Infix Expressions Infix expressions are the kind we use in Java –6*3+7 –6+3*7 –(6+3) * 7 Order of operation depends on precedence –Multiplication first, then addition –Parentheses override order –Otherwise, left to right

31 Converting Infix to Postfix Operands (numbers) stay in the same order Operators go in after their operands are complete –6*3+7 - 6 3 * 7 + –6+3*7 6 3 7 * + –(6+3) * 7 6 3 + 7 * How to decide when to insert the operator?

32 Algorithm for Infix to Postfix For each token –If it is an operand, insert it immediately in the result –If it is an operator –While stack is not empty AND this operator has lower precedence than top-of-stack operator – pop operator from stack into expression – push this operator Pop remaining operators into expression

33 Examples –6*3+7 6 3 * 7 + –6+3*7 6 3 7 * +

34 What about parentheses? When you see a left parenthesis, push it on the stack When you see a right parenthesis, pop all operators back to the left paren Why? –Parentheses delimit a new expression –Right paren acts like end of expression (pop all remaining operators at the end)

35 Example –(6+3) * 76 3 + 7 *

36 A Search Problem Given a sequence of flight segments, can you reach one city from the other? If there is a flight from A to B, then A and B are adjacent (A->B) If (A->B) and (B->C), we can reach C from A

37 Recursive Solution (pseudocode) bool canReach(city A, city B){ If (A == B) return true; //trivial problem If (adjacent(A,B)) return true; //direct flight For (each city adjacent to A) if canReach(city, B) return true; Return false; }

38 Stack-based solution (pseudocode) bool canReach(city A, city B){ If (A == B) return true; //trivial problem Else push A onto the stack While(stack is not empty and top != B) if the city has an unvisited neighbor mark the neighbor as visited push the neighbor on the stack else pop the stack; } If the stack is empty return false; Otherwise return true (and the path is on the stack!) }

39 Comments on stack based search No essential difference between recursive and stack algorithms This algorithm is called “depth-first search” Path that is found will not necessarily be the shortest Order of visits doesn’t matter for correctness, but matters significantly for efficiency


Download ppt "Implementing Stacks Ellen Walker CPSC 201 Data Structures Hiram College."

Similar presentations


Ads by Google