Title: Recursion
1Recursion
To Iterate is Human, to Recurse, Divine L.
Peter Deutsch
2Functions reminder
return-type name(arg_type1 arg_name1, arg_type2
arg_name2, ) function body return value
- a group of variables and statements that is
assigned a name - a sub-program
- A function can call other functions.
3Return Statement - reminder
- Return causes the execution of the function to
terminate and returns a value to the calling
function. - The type of the value returned must be the same
as the return-type defined for the function
4Scope of variables - reminder
- A variable declared within a function is
unrelated to variables declared elsewhere - A function cannot access variables that are
declared in other functions
5Func. Declaration - reminder
- We can call a function from the point in the file
in which the function has been declared, until
the end of the file.
return-type name(arg_type1 arg_name1, arg_type2
arg_name2, )
6Recursive Function
- A function defined in terms of itself is called a
recursive function.
return_value rec_func(type arg1, type arg2, )
rec_func()
7Factorial
- As we saw, n! 123 (n-1)n
- Thus, we can also define factorial the following
way - 0! 1
- n! n(n-1)! for ngt0
n
8A recursive definition
- C functions can also call themselves!
- However, not with the same parameters (why?)
- Some functions can be defined using smaller
occurrences of themselves. - Such a definition is called a recursive
definition of a function. - Every recursive function has a boundary
condition. The function stops calling itself
when it is satisfied. - Why is this necessary?
9Example - factorial
- int fact_rec(int n)
-
- if (n 0)
- return 1
- return n fact_rec(n-1)
- int fact_itr(int n)
-
- int fact 1 while (n gt 1)
-
- fact n
- --n return fact
10Recursive factorial step by step
n ? 4return ? ?
- int fact_rec(int n)
-
- if (n 0)
- return 1
- return n fact_rec(n-1)
11Recursive factorial step by step
n ? 4return ? 4 ?
- int fact_rec(int n)
-
- if (n 0)
- return 1
- return n fact_rec(n-1)
12Recursive factorial step by step
n ? 4return ? 4 ?
- int fact_rec(int n)
-
- if (n 0)
- return 1
- return n fact_rec(n-1)
n ? 3return ? ?
13Recursive factorial step by step
n ? 4return ? 4 ?
- int fact_rec(int n)
-
- if (n 0)
- return 1
- return n fact_rec(n-1)
n ? 3return ? 3 ?
14Recursive factorial step by step
n ? 4return ? 4 ?
- int fact_rec(int n)
-
- if (n 0)
- return 1
- return n fact_rec(n-1)
n ? 3return ? 3 ?
n ? 2return ? ?
15Recursive factorial step by step
n ? 4return ? 4 ?
- int fact_rec(int n)
-
- if (n 0)
- return 1
- return n fact_rec(n-1)
n ? 3return ? 3 ?
n ? 2return ? 2 ?
16Recursive factorial step by step
n ? 4return ? 4 ?
- int fact_rec(int n)
-
- if (n 0)
- return 1
- return n fact_rec(n-1)
n ? 3return ? 3 ?
n ? 2return ? 2 ?
n ? 1return ? ?
17Recursive factorial step by step
n ? 4return ? 4 ?
- int fact_rec(int n)
-
- if (n 0)
- return 1
- return n fact_rec(n-1)
n ? 3return ? 3 ?
n ? 2return ? 2 ?
n ? 1return ? 1 ?
18Recursive factorial step by step
- int fact_rec(int n)
-
- if (n 0)
- return 1
- return n fact_rec(n-1)
19Recursive factorial step by step
- int fact_rec(int n)
-
- if (n 0)
- return 1
- return n fact_rec(n-1)
20Recursive factorial step by step
n ? 4return ? 4 ?
- int fact_rec(int n)
-
- if (n 0)
- return 1
- return n fact_rec(n-1)
n ? 3return ? 3 ?
n ? 2return ? 2 ?
n ? 1return ? 1 1
21Recursive factorial step by step
n ? 4return ? 4 ?
- int fact_rec(int n)
-
- if (n 0)
- return 1
- return n fact_rec(n-1)
n ? 3return ? 3 ?
n ? 2return ? 2 1
22Recursive factorial step by step
n ? 4return ? 4 ?
- int fact_rec(int n)
-
- if (n 0)
- return 1
- return n fact_rec(n-1)
n ? 3return ? 3 2
23Recursive factorial step by step
n ? 4return ? 4 6
- int fact_rec(int n)
-
- if (n 0)
- return 1
- return n fact_rec(n-1)
24Another Example
- void print_nums(int num)
-
- if (num 0)
- return
- printf("d ", num)
- print_nums(num - 1)
- printf("d ", num)
3 2 1 1 2 3
printcall funcprint
3
printcall funcprint
2
printcall funcprint
1
return
0
25What does it do?
- void foo()
-
- int num
- scanf("d", num)
- if (num lt 0)
- return
- foo()
- printf("d ", num)
-
26Reverse Print
- void reverse_print()
-
- int num
- scanf("d", num)
- if (num lt 0)
- return
- reverse_print()
- printf("d ", num)
Reads an unbounded series of numbers from the
user and prints them in reverse order.
27Another example - power
- Xy xxx
- Recursive definitions (assume non-negative y)
1, y 0 Xy Xy-1, y
odd (Xy/2)2, y even
y times
28rec_pow
- int rec_pow(int x, int y)
-
- if (y 0)
- return 1
- if (y 2 0)
- return square(rec_pow(x, y / 2))
- else
- return x rec_pow(x, y - 1)
29The Three Rules of Recursion
- Know when to stop.
- Decide how to take one step.
- Break the problem down into that step plus a
smaller problem.
30Exercise
- Write a program that receives two non-negative
integers and computes their product recursively. - Hint Notice that the product ab is actually
aaa (b times).
31Solution
- int rec_mul(int a, int b)
-
- / base condition a 0 0 /
- if (b 0)
- return 0
- / save a and call recursively /
- return a rec_mul(a, b-1)
32Exercise
- int sum_digits(int n)
-
- int sum 0
- while (n gt 0)
-
- sum n10 n n/10
-
- return sum
- Given the following iterative version of
sum-of-digits calculation - Find the recursive definition of this function
- (dont forget the base case!)
33Solution
- int sum_digit_rec(int n)
-
- return (n 0) ? 0 n 10
sum_digit_rec(n / 10)
34More uses
- Recursion is a general approach to programming
functions - Its uses are not confined to calculating
mathematical expressions! - For example max_rec.c
35max_rec step by step
- int rec_max(int arr , int size)
-
- int rest
- if (size 1)
- return arr0
- else
-
- rest rec_max(arr1, size-1)
- if (arr0 gt rest)
- return arr0
- else
- return rest
-
36max_rec step by step
- int rec_max(int arr , int size)
-
- int rest
- if (size 1)
- return arr0
- else
-
- rest rec_max(arr1, size-1)
- if (arr0 gt rest)
- return arr0
- else
- return rest
-
37max_rec step by step
- int rec_max(int arr , int size)
-
- int rest
- if (size 1)
- return arr0
- else
-
- rest rec_max(arr1, size-1)
- if (arr0 gt rest)
- return arr0
- else
- return rest
-
38max_rec step by step
- int rec_max(int arr , int size)
-
- int rest
- if (size 1)
- return arr0
- else
-
- rest rec_max(arr1, size-1)
- if (arr0 gt rest)
- return arr0
- else
- return rest
-
39max_rec step by step
- int rec_max(int arr , int size)
-
- int rest
- if (size 1)
- return arr0
- else
-
- rest rec_max(arr1, size-1)
- if (arr0 gt rest)
- return arr0
- else
- return rest
-
40max_rec step by step
- int rec_max(int arr , int size)
-
- int rest
- if (size 1)
- return arr0
- else
-
- rest rec_max(arr1, size-1)
- if (arr0 gt rest)
- return arr0
- else
- return rest
-
41max_rec step by step
- int rec_max(int arr , int size)
-
- int rest
- if (size 1)
- return arr0
- else
-
- rest rec_max(arr1, size-1)
- if (arr0 gt rest)
- return arr0
- else
- return rest
-
42max_rec step by step
- int rec_max(int arr , int size)
-
- int rest
- if (size 1)
- return arr0
- else
-
- rest rec_max(arr1, size-1)
- if (arr0 gt rest)
- return arr0
- else
- return rest
-
43max_rec step by step
- int rec_max(int arr , int size)
-
- int rest
- if (size 1)
- return arr0
- else
-
- rest rec_max(arr1, size-1)
- if (arr0 gt rest)
- return arr0
- else
- return rest
-
44max_rec step by step
- int rec_max(int arr , int size)
-
- int rest
- if (size 1)
- return arr0
- else
-
- rest rec_max(arr1, size-1)
- if (arr0 gt rest)
- return arr0
- else
- return rest
-
45max_rec step by step
- int rec_max(int arr , int size)
-
- int rest
- if (size 1)
- return arr0
- else
-
- rest rec_max(arr1, size-1)
- if (arr0 gt rest)
- return arr0
- else
- return rest
-
46max_rec step by step
- int rec_max(int arr , int size)
-
- int rest
- if (size 1)
- return arr0
- else
-
- rest rec_max(arr1, size-1)
- if (arr0 gt rest)
- return arr0
- else
- return rest
-
47max_rec step by step
- int rec_max(int arr , int size)
-
- int rest
- if (size 1)
- return arr0
- else
-
- rest rec_max(arr1, size-1)
- if (arr0 gt rest)
- return arr0
- else
- return rest
-
48max_rec step by step
- int rec_max(int arr , int size)
-
- int rest
- if (size 1)
- return arr0
- else
-
- rest rec_max(arr1, size-1)
- if (arr0 gt rest)
- return arr0
- else
- return rest
-
49max_rec step by step
- int rec_max(int arr , int size)
-
- int rest
- if (size 1)
- return arr0
- else
-
- rest rec_max(arr1, size-1)
- if (arr0 gt rest)
- return arr0
- else
- return rest
-
50max_rec step by step
- int rec_max(int arr , int size)
-
- int rest
- if (size 1)
- return arr0
- else
-
- rest rec_max(arr1, size-1)
- if (arr0 gt rest)
- return arr0
- else
- return rest
-
51max_rec step by step
- int rec_max(int arr , int size)
-
- int rest
- if (size 1)
- return arr0
- else
-
- rest rec_max(arr1, size-1)
- if (arr0 gt rest)
- return arr0
- else
- return rest
-
52max_rec step by step
- int rec_max(int arr , int size)
-
- int rest
- if (size 1)
- return arr0
- else
-
- rest rec_max(arr1, size-1)
- if (arr0 gt rest)
- return arr0
- else
- return rest
-
53max_rec step by step
- int rec_max(int arr , int size)
-
- int rest
- if (size 1)
- return arr0
- else
-
- rest rec_max(arr1, size-1)
- if (arr0 gt rest)
- return arr0
- else
- return rest
-
54max_rec step by step
- int rec_max(int arr , int size)
-
- int rest
- if (size 1)
- return arr0
- else
-
- rest rec_max(arr1, size-1)
- if (arr0 gt rest)
- return arr0
- else
- return rest
-
55max_rec step by step
- int rec_max(int arr , int size)
-
- int rest
- if (size 1)
- return arr0
- else
-
- rest rec_max(arr1, size-1)
- if (arr0 gt rest)
- return arr0
- else
- return rest
-
56max_rec step by step
- int rec_max(int arr , int size)
-
- int rest
- if (size 1)
- return arr0
- else
-
- rest rec_max(arr1, size-1)
- if (arr0 gt rest)
- return arr0
- else
- return rest
-
57max_rec step by step
- int rec_max(int arr , int size)
-
- int rest
- if (size 1)
- return arr0
- else
-
- rest rec_max(arr1, size-1)
- if (arr0 gt rest)
- return arr0
- else
- return rest
-
58max_rec step by step
- int rec_max(int arr , int size)
-
- int rest
- if (size 1)
- return arr0
- else
-
- rest rec_max(arr1, size-1)
- if (arr0 gt rest)
- return arr0
- else
- return rest
-
59max_rec step by step
- int rec_max(int arr , int size)
-
- int rest
- if (size 1)
- return arr0
- else
-
- rest rec_max(arr1, size-1)
- if (arr0 gt rest)
- return arr0
- else
- return rest
-
60max_rec step by step
- int rec_max(int arr , int size)
-
- int rest
- if (size 1)
- return arr0
- else
-
- rest rec_max(arr1, size-1)
- if (arr0 gt rest)
- return arr0
- else
- return rest
-
61What does it do?
- char rec_func(char str, char c)
-
- if (str '\0')
- return NULL
- if (str c)
- return str
- return rec_func(str, c)
62Solution
- A recursive implementation of strchr
- See strchr_rec.c
63Exercise
- Write a recursive implementation of strcmp
- Input two strings
- Output 0 if both are equal, 1 if not
- Write a program that accepts two strings from the
user and checks whether they are equal
64Solution
- int rec_strcmp(char s1, char s2)
-
- if (s1 ! s2)
- return s1 - s2
- if (s1 '\0') return 0
- return rec_strcmp(s1, s2)
65Towers of Hanoi
- Goal
- Move the entire tower to the dst peg.
- Constraints
- Only move one disk at a time.
- Never place a larger disk on a smaller one.
src
dst
aux
66Towers of Hanoi
Step 1 Move n 1 disks from src to aux using
dst.
src
dst
aux
67Towers of Hanoi
Step 1 Move a single disk from src to dst
src
dst
aux
68Towers of Hanoi
Step 3 Move n 1 disks from aux to dst using src
src
dst
aux
69Towers of Hanoi - C
- void hanoi(int n, char src, char
aux, char dst) -
- if (n 1)
- printf("move disk from s to s\n", src,
dst) - else
- hanoi(n - 1, src, dst, aux)
- hanoi(1, src, NULL, dst)
- hanoi(n - 1, aux, src, dst)
-
70(No Transcript)