10 recursion © 2010 david a watt, university of glasgow accelerated programming 2 part i: python...

21
10 Recursion © 2010 David A Watt, University of Glasgow Accelerated Programming 2 Part I: Python Programming 1

Upload: felicia-wade

Post on 13-Jan-2016

218 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: 10 Recursion © 2010 David A Watt, University of Glasgow Accelerated Programming 2 Part I: Python Programming 1

10Recursion

© 2010 David A Watt, University of Glasgow

Accelerated Programming 2

Part I: Python Programming

1

Page 2: 10 Recursion © 2010 David A Watt, University of Glasgow Accelerated Programming 2 Part I: Python Programming 1

10-2

Recursive functions

A recursive function is one that calls itself.

Some programming problems can be solved using either recursion or iteration.

– A recursive solution is usually more elegant (easier to write, easier to understand).

– An iterative solution is usually more efficient.

Some problems are definitely solved best by using recursion.

Page 3: 10 Recursion © 2010 David A Watt, University of Glasgow Accelerated Programming 2 Part I: Python Programming 1

10-3

Example: recursion vs iteration (1)

Consider the mathematical definition of bn, where n is a non-negative integer:

bn = 1 if n = 0bn = b ₓ bn–1 if n > 0

This definition is recursive, and immediately suggests a recursive function:

def power (b, n): if n == 0: return 1 else: return b * power(b, n-1)

Page 4: 10 Recursion © 2010 David A Watt, University of Glasgow Accelerated Programming 2 Part I: Python Programming 1

10-4

Example: recursion vs iteration (2)

Of course iteration works too:

def power (b, n): p = 1 for i in range(0, n): p *= b return p

Which version is better?

Page 5: 10 Recursion © 2010 David A Watt, University of Glasgow Accelerated Programming 2 Part I: Python Programming 1

10-5

Example: recursion vs iteration (3)

Now consider this alternative definition of bn:

bn = 1 if n = 0bn = (bn//2)2 if n > 0 and n is evenbn = b ₓ (bn//2)2 if n > 0 and n is odd

Note:

– If n is even, n//2 = ½n.

– If n is odd, n//2 = ½(n–1).

Page 6: 10 Recursion © 2010 David A Watt, University of Glasgow Accelerated Programming 2 Part I: Python Programming 1

10-6

Example: recursion vs iteration (4)

This definition is recursive, and suggests a alternative recursive function:

def power (b, n): if n == 0: return 1 else: p = power(b, n//2) if n%2 == 0: return p * p else: return b * p * p

This version is much more efficient, but harder to express using iteration. (Try it!)

Page 7: 10 Recursion © 2010 David A Watt, University of Glasgow Accelerated Programming 2 Part I: Python Programming 1

10-7

When does recursion work?

We must take care to ensure that a recursive function does not go on calling itself forever.

Every recursive function should have at least one “easy” case and at least one “hard” case .

– In an easy case, the function does not call itself.

– In a hard case, the function calls itself but only to deal with an easier case.

E.g., recursive power function:

– When n is 0, it does not call itself.

– When n is non-0, it calls itself with a smaller value than n.

Page 8: 10 Recursion © 2010 David A Watt, University of Glasgow Accelerated Programming 2 Part I: Python Programming 1

10-8

Example: Towers of Hanoi (1)

Three vertical poles are mounted on a platform.

A number of discs are provided, all with different diameters. Each disc has a hole in its centre.

All discs are initially threaded on to pole 1, forming a tower with the largest disc at the bottom and the smallest disc at the top.

pole 1 pole 2 pole 3

Page 9: 10 Recursion © 2010 David A Watt, University of Glasgow Accelerated Programming 2 Part I: Python Programming 1

10-9

Example: Towers of Hanoi (2)

One disc may be moved at a time, from the top of one pole to the top of another pole.

A larger disc may not be moved on top of a smaller disc.

Problem: Move the tower of discs from pole 1 to pole 2.

Page 10: 10 Recursion © 2010 David A Watt, University of Glasgow Accelerated Programming 2 Part I: Python Programming 1

10-10

Example: Towers of Hanoi (3)

Animation (with 2 discs):

pole 1 pole 2 pole 3pole 1 pole 2 pole 3pole 1 pole 2 pole 3pole 1 pole 2 pole 3

Page 11: 10 Recursion © 2010 David A Watt, University of Glasgow Accelerated Programming 2 Part I: Python Programming 1

10-11

Example: Towers of Hanoi (4)

Implementation:

def hanoi (n): # Move a tower of n discs from tower 1 to tower 2. move_tower(n, 1, 2, 3)

def move_tower (n, a, b, c): # Move a tower of n discs from the top of tower a # to the top of tower b, using tower c as a spare. if n == 1: move_disc(a, b) else: move_tower(n-1, a, c, b) move_disc(a, b) move_tower(n-1, c, b, a)

Page 12: 10 Recursion © 2010 David A Watt, University of Glasgow Accelerated Programming 2 Part I: Python Programming 1

10-12

Example: Towers of Hanoi (5)

Implementation (continued):

def move_disc (a, b): # Move a single disc from tower a to tower b. print 'Move disc from %d to %d.' \ % (a, b)

Output (with 3 discs):

Move disc from 1 to 2.Move disc from 1 to 3.Move disc from 2 to 3.Move disc from 1 to 2.Move disc from 3 to 1.Move disc from 3 to 2.Move disc from 1 to 2.

Page 13: 10 Recursion © 2010 David A Watt, University of Glasgow Accelerated Programming 2 Part I: Python Programming 1

10-13

Animation (with 3 discs):

pole 1 pole 2 pole 3pole 1 pole 2 pole 3pole 1 pole 2 pole 3pole 1 pole 2 pole 3

Example: Towers of Hanoi (6)

Page 14: 10 Recursion © 2010 David A Watt, University of Glasgow Accelerated Programming 2 Part I: Python Programming 1

10-14

Animation (with 6 discs):

Example: Towers of Hanoi (7)

pole 1 pole 2 pole 3pole 1 pole 2 pole 3pole 1 pole 2 pole 3pole 1 pole 2 pole 3

Page 15: 10 Recursion © 2010 David A Watt, University of Glasgow Accelerated Programming 2 Part I: Python Programming 1

10-15

A data structure is a collection of data (elements) organised in a systematic way.

A list is a data structure whose elements are organised in a sequence.

A tree is a data structure whose elements are organised in a hierarchy. Each element in a tree may have 0 or more subtrees, which are themselves trees.

Thus a tree is a recursive data structure.

Most functions on trees are naturally recursive.

Recursive data structures

Page 16: 10 Recursion © 2010 David A Watt, University of Glasgow Accelerated Programming 2 Part I: Python Programming 1

10-16

A family tree represents family relationships.

For simplicity, consider a family tree showing just the descendants of a particular person:

Example: family trees (1)

Margaret Ann

JeffSusanne Jon

Frank

David

Emma

Page 17: 10 Recursion © 2010 David A Watt, University of Glasgow Accelerated Programming 2 Part I: Python Programming 1

10-17

We can represent a family tree in Python by a pair (name, children), where name is a string and children is a list of (0 or more) subtrees:

family = \ ('Frank', [ \ ('David', [ \ ('Susanne', []), \ ('Jeff', []) ]), \ ('Margaret', []), \ ('Ann', [ \ ('Emma', []), \ ('Jon', []) ]) ])

Example: family trees (2)

Page 18: 10 Recursion © 2010 David A Watt, University of Glasgow Accelerated Programming 2 Part I: Python Programming 1

10-18

Simple functions on a family tree:

def gen1 (family): # Return the name of the 1st generation of family. return family[0]

def gen2 (family): # Return a list of the names of the 2nd generation of # family. return [child[0] for child in family[1]]

E.g.:

gen1(family) yields ‘Frank’

gen2(family) yields [‘David’, ‘Margaret’, ‘Ann’]

Example: family trees (3)

Page 19: 10 Recursion © 2010 David A Watt, University of Glasgow Accelerated Programming 2 Part I: Python Programming 1

10-19

Function to list all members of an extended family:

def all (family): # Return a list of names of all persons in the # tree family. (name, children) = family descendants = concat( \ [all(child) for child in children]) return [name] + descendants

This assumes:

concat(ls) returns the concatenation of a list of lists ls

Example: family trees (4)

Page 20: 10 Recursion © 2010 David A Watt, University of Glasgow Accelerated Programming 2 Part I: Python Programming 1

10-20

Function to search an extended family:

def search (family, name): # Search family for the person with name # and return the corresponding subtree. # Return () if name is not found. # Assume that names are unique. (fname, fchildren) = family if fname == name: return family else: return search_list(fchildren, name)

Example: family trees (5)

Page 21: 10 Recursion © 2010 David A Watt, University of Glasgow Accelerated Programming 2 Part I: Python Programming 1

10-21

Auxiliary function to search a list of children:

def search_list (families, name): # Search families for the person with name # and return the corresponding subtree. # Return () if name is not found. if len(families) == 0: return () else: fam = search(families[0], name) if fam != (): return fam else: return search_list( \ families[1:], name)

Example: family trees (6)