Computer Science 112 Fundamentals of Programming II Introduction to Stacks

Preview:

Citation preview

Computer Science 112

Fundamentals of Programming IIIntroduction to Stacks

The Stack Collection: Overview

• Formal properties

• Applications

• Implementations

Formal Properties of Stacks

• Stacks are like lists in that elements are ordered by position (linear)

• However, access is only at one end, called the top

• A stack enforces last-in, first-out (LIFO) access

LIFO Access

D

D

D

D

D

D

Dpush

D

D

Dpop

Top of stack

s.isEmpty() Returns True if empty, False otherwise

len(s) Returns the number of items in the stack

str(s) Returns a string representation

iter(s) Supports a for loop

item in s True if item is in stack, False otherwise

s1 + s2 Returns a new stack with items in s1 and s2

s1 == s2 Equality test for two stacks

Minimal Set of Stack Operations

s.isEmpty() Returns True if empty, False otherwise

len(s) Returns the number of items in the stack

str(s) Returns a string representation

iter(s) Supports a for loop

item in s True if item is in stack, False otherwise

s1 + s2 Returns a new stack with items in s1 and s2

s1 == s2 Equality test for two stacks

s.push(item) Adds item to the top of the stack

s.pop() Removes and returns top item

s.peek() Returns item at the top of the stack

The precondition of pop and peek is that the stack is not empty.

Minimal Set of Stack Operations

Stack Implementations

• Array-based

• Singly linked structure

• Always a single set of abstract operations

stack1 = LinkedStack()stack2 = ArrayStack([1, 2, 3, 4])

The Stack Resources

LinkedStack ArrayStack

StackInterface

AbstractStack

AbstractCollection

stack = LinkedStack() # or ArrayStack()

stack.push("A string")stack.push("Another string")

for item in stack: print(item)

while not stack.isEmpty(): print(stack.pop())

Example Use of a Stack

We have a single set of abstract operations and two implementing classes, ArrayStack and LinkedStack

The Stack Iterator

stack1 = LinkedStack([1, 2, 3, 4])

stack2 = ArrayStack(stack1)

for item in stack1: print(item)

for item in stack2: print(item)

stack3 = ArrayStack(stack2)

Does the iterator start at the top or the bottom of the stack?

Stack Applications

Stacks are useful for algorithms that must backtrack to the most recent data element in a series of elements– Run-time support of recursion– Language processing– Game playing, puzzle solving– Tree and graph traversals

Example: N!N! = 1, when N = 1N! = N * (N - 1)!, otherwise

Recursive definition:

def factorial(n): if n == 1: return 1 else: return n * factorial(n – 1)

Recursive function:

factorial(4) -> 4 * factorial(3) -> 3 * factorial(2) -> 2 * factorial(1) -> 1 <- 2 <- 6 <-24 <-

Runtime trace:

How Recursion Works

• Each call of a function generates an instance of that function

• An instance of a function contains– memory for each parameter– memory for each local variable– memory for the return value– a pointer to the caller’s next instruction (return

address)

• This chunk of memory is also called an activation record

Example: factorial(4)

4nreturn value Activation record for factorial(4)

def factorial(n): if n == 1: return 1 else: return n * factorial(n – 1)

Activations Are Added Dynamically

4nreturn value Activation record for factorial(4)

3nreturn value Activation record for factorial(3)

def factorial(n): if n == 1: return 1 else: return n * factorial(n – 1)

Number of Activations = # Calls

4nreturn value Activation record for factorial(4)

3nreturn value Activation record for factorial(3)

2nreturn value Activation record for factorial(2)

def factorial(n): if n == 1: return 1 else: return n * factorial(n – 1)

Recursive Process Bottoms out

4nreturn value Activation record for factorial(4)

3nreturn value Activation record for factorial(3)

2nreturn value Activation record for factorial(2)

1nreturn value Activation record for factorial(1)

def factorial(n): if n == 1: return 1

Recursive Process Unwinds

4nreturn value Activation record for factorial(4)

3nreturn value Activation record for factorial(3)

2nreturn value Activation record for factorial(2)

1

1

nreturn value Activation record for factorial(1)

def factorial(n): if n == 1: return 1

Activations Are Deallocated

4nreturn value Activation record for factorial(4)

3nreturn value Activation record for factorial(3)

2

2

nreturn value Activation record for factorial(2)

def factorial(n): if n == 1: return 1 else: return n * factorial(n – 1)

Activations Are Deallocated

4nreturn value Activation record for factorial(4)

3

6

nreturn value Activation record for factorial(3)

def factorial(n): if n == 1: return 1 else: return n * factorial(n – 1)

Value Returned Is in the First Activation

4

24

nreturn value Activation record for factorial(4)

def factorial(n): if n == 1: return 1 else: return n * factorial(n – 1)

def factorialWithLoopAndStack(n): stack = LinkedStack()

Loop with Explicit Stack

def factorialWithLoopAndStack(n): stack = LinkedStack()

# Load up the stack with the sequence of numbers from n # down to 1. while n >= 1: stack.push(n) n -= 1

Loop with Explicit Stack

def factorialWithLoopAndStack(n): stack = LinkedStack()

# Load up the stack with the sequence of numbers from n # down to 1. while n >= 1: stack.push(n) n -= 1

# Pop the top two numbers and push their product onto the # stack, until there is just one number left on the stack. while len(stack) > 1: operand1 = stack.pop() operand2 = stack.pop() product = operand1 * operand2 stack.push(product)

Loop with Explicit Stack

def factorialWithLoopAndStack(n): stack = LinkedStack()

# Load up the stack with the sequence of numbers from n # down to 1. while n >= 1: stack.push(n) n -= 1

# Pop the top two numbers and push their product onto the # stack, until there is just one number left on the stack. while len(stack) > 1: operand1 = stack.pop() operand2 = stack.pop() product = operand1 * operand2 stack.push(product)

# Return the number at the top of the stack. return stack.peek()

Loop with Explicit Stack

Matching Parentheses

expression = { letter } | "(" expression ")"

a ab (a) ((a)) (a(b)c) () (())

a( )( a) ((())

Grammar:

Legalexpressions:

Illegalexpressions:

An expression is either a sequence of zero or moreletters or an expression within parentheses.

Create a new stackSet match to trueFor each character in the string If the character equals '(' Push the character onto the stack Else If the character equals ')' If the stack is empty Set match to false Break Else Pop the top '(' from the stackIf the stack is not empty Set match to falseReturn match

Parentheses Matching Algorithm

def inputOk(s): stack = LinkedStack() match = True for ch in s: if ch == '(': stack.push(ch) elif ch == ')': if stack.isEmpty(): # No matching ( match = False break else: stack.pop() if not stack.isEmpty(): # No matching ) match = False return match

Python Code

For Monday

More stack applications

Recommended