1. 程式人生 > 其它 >[2021 Spring] CS61A 學習筆記 lecture 7 tree recursion

[2021 Spring] CS61A 學習筆記 lecture 7 tree recursion

lecture7 主要講樹遞迴、線性遞迴、尾遞迴。
課本:http://composingprograms.com/pages/17-recursive-functions.html

目錄

遞迴分類

樹遞迴:每次呼叫會多次呼叫自身

線性遞迴:每次呼叫最多進行一次遞迴呼叫

尾遞迴:每次呼叫最多進行一次遞迴呼叫,且只執行自身呼叫(沒有其他變數)

關於尾遞迴的說明,參考StackOverflow上的What is tail recursion

問題 find_zero

尾遞迴1

尾遞迴2

線性遞迴

樹遞迴

可以呼叫多次,但是不是必須的

Finding a Path

Path-Finding Program

每一步都要向下移動一格,向左右移動不超過一格。

is_path Solution

def is_path(blocked, x0, y0):
   """True iff there is a path of squares from (X0, Y0) to some 
   square (x1, 0) such that all squares on the path (including first and
   last) are unoccupied.  BLOCKED is a predicate such that BLOCKED(x, y) 
   is true iff the grid square at (x, y) is occupied or off the edge.
   Each step of a path goes down one row and 1 or 0 columns left or right."""

   if blocked(x0, y0):
       return False
   elif y0 == 0:
       return True
   else:
       return (is_path(blocked, x0-1, y0-1) 
              or is_path(blocked, x0, y0-1) 
              or is_path(blocked, x0+1, y0-1))

Counting the Paths

num_paths Solution

def num_paths(blocked, x0, y0):
   """Return the number of unoccupied paths that run from (X0, Y0)
   to some square (x1, 0). BLOCKED is a predicate such that BLOCKED(x, y) 
   is true iff the grid square at (x, y) is occupied or off the edge. """

   if blocked(x0, y0):
       return 0
   elif y0 == 0:
       return 1
   else:
       return num_paths(blocked, x0, y0-1) \
            + num_paths(blocked, x0-1, y0-1) \
            + num_paths(blocked, x0+1, y0-1)
# OR (looking ahead a bit)
#      return sum( (num_paths(blocked, x0+k, y0-1)
#                   for k in range(-1, 2))
#                )

A Change in Problem

change:不限制移動時必須向下移動一格,會導致無限遞迴

And a Little Analysis

is_path每次呼叫會呼叫三次自身,初始y位置為y0,可能的呼叫次數就可能達到3**y0,指數式增長。

Another Recursion Problem: Counting Partitions

Identifying the Problem in the Problem

Counting Partitions: Code

兩種情況:選擇k和不選擇k

def num_partitions(n, k):
    """Return number of distinct ways to express N as a sum of 
    positive integers each of which is <= K, where K > 0."""
    if n < 0:
        return 0
    elif k == 1:
        return 1
    else:
        return num_partitions(n-k, k) + num_partitions(n, k-1)

Recurrences

斐波那契遞迴,複雜度很高,簡化方法後面會講到。