Recursion Recursion 递归） 1 Introduction to Recursion Principles of by yurtgc548

VIEWS: 4 PAGES: 76

• pg 1
```									         Recursion (递归）

1. Introduction to Recursion
-- Principles of recursion
-- Recursion trees
2. How recursion is implemented on the machine
-- Stacks and recursion
3. Analyzing Recursion
-- when to use recursion
4. Backtracking (回溯法）– a method to try all
possibilities using recursion
An algorithm is recursive (递归的) if it calls
itself (directly or indirectly) to do part of its
work.
Factorials: A recursive definition
• In Mathematics:

Base case
（递归基）

General case that
reduces to simpler
case（递归步）
+: concise and elegant
-: can require keeping track of many
partial computations
The process of recursive call
Every recursive process consists of two parts:
1. A smallest, base case that gives a solution;
2. A general method that reduces a particular case
to one or more of the smaller cases, reducing
the problem all the way to the base case
eventually.
The tower of Hanoi

Task: move the tower from 1 to 3 using 2 as
temporary storage.
Rules: 1. move only one disk at one time;
2. No larger disk can be placed on a
smaller disk.
Divide and conquer(分治法）
1                     2                      3

We have to get to this state and then move
the bottom disk
1                  2   3

A similar problem
1    2          3

Solved by
recursion
The Solution

184467440737095551615天才能完成，照這樣看來，這世界還算蠻

Our goal: move(8, 1, 3, 2)
Our goal: move(8, 1, 3, 2)

Steps to solve the problem:
move(7, 1, 2, 3); /*move 7 disks from tower 1
to 2 */
cout << “move disk 8 from tower 1 to
3.”<<endl;
move(7, 2, 3, 1); /* move 7 disks from tower
2 to 3 */
Recursive Function

The base case is
count == 0
Designing recursive algorithms
Tree of function calls(函数调用树)
Tree of function calls is a tool to analyzing the process of
function calls.
• A node(结点) denotes a function call with the function
name;
• A function may invokes other functions, which are
denoted as children;
• Different recursive calls appear as different vertices
with the same name;
• Recursion tree: the recursive part of the tree of function
calls.
invoke the
function
Meaning of the tree of
function calls: the
traversal of the tree is
the trace of the function
calls

Return from
the function
Tree of function calls and the
execution order

Recursive call

Execution
order
Recursion tree for three disks
Number of nodes is
the number of disk
movements.
The number of moves to solve Hanoi for
64 disks?
The number of inner nodes:
1+2+22+ … +263 = 264 – 1 ≈ 1.6 × 1019
It will take more than 500 billion (五千亿年）years to
finish the task suppose one can move one disk every
second.

Note also that our program also produces the best
possible solution.
Recursion (递归）

1. Introduction to Recursion
-- Solving problems using recursion
-- Recursion trees
2. How recursion is implemented on the machine
-- Stacks and recursion
3. Analyzing Recursion
-- when to use recursion
4. Backtracking (回溯法）– a method to try all
possibilities using recursion
Recursion and Stacks

• Recursive calls are implemented by using stacks;
• Recursion can be replaced by stacks and
iteration (迭代);
Function A calls B, B calls C:
Save returning
parameters                            C

Start from the
First started, last
finished
Computation process of factorial (4)
Factorial(4) = 4*factorial(3)
3*factorial(2)
2*factorial(1)
1*factorial(0)
1*1
Stack Frames for Subprograms
When a program calls a subprogram, the system:
• Store returning location and parameters;
• Allocate storage for all the local variables.
• Then the control is passed to the subprogram.

parameters is stored in the activation record(活

When the subprogram is finished,
• Return the result of the subprogram;
• Release the storage allocated for the subprogram;
• the control is passed to the caller and execution
Temporary storage areas for use by functions would
be allocated in a list with the property last in, first
out.
So, stack is the data structure to manage function
call mechanism.
When a function call is made:
• the activation record is pushed into the stack, and
• when the function is finished, the activation record
for the function is popped off.
D calls itself

Activation record for
the main program M
Stack frames(运行栈): each column shows the stack contents at a given time:
• A function may call itself. There is no difference
between this recursive call and other function calls.
• For each recursive call, an activation record for the
instance of the call is pushed into the stack.
L1:
L2:

L3:

L4:

int main() {
move(2,1,3,2);
L0:   : ….;
Stack frames for move(2, 1, 3, 2)
Activation record:

L2, 0, 1, 3, 2
L2, 1, 1, 2, 3
L0, 2, 1, 3, 2
Return, Pop(), goto L2

L2, 0, 1, 2, 3
L2, 1, 1, 2, 3
L0, 2, 1, 3, 2

Starting from L2,
move disk 1 from 1
to 2

L2, 1, 1, 2, 3
L0, 2, 1, 3, 2
Recursive call at L3, so push()
L4, 0, 3, 2, 1
L2, 1, 1, 2, 3
L0, 2, 1, 3, 2

Return, pop(), then
goto L4

L2, 1, 1, 2, 3
L0, 2, 1, 3, 2
Starting at L4, so pop() again,
and goto L2

L2, 1, 1, 2, 3
L0, 2, 1, 3, 2

Do L2: move disk 2
from 1 to 3

L0, 2, 1, 3, 2
Recursive call
Recursive call
at L1
at L3

L2, 0, 2, 1, 3
L4, 1, 2, 3, 1
L0, 2, 1, 3, 2
Pop(), goto L2

L2, 0, 2, 1, 3
L4, 1, 2, 3, 1
L0, 2, 1, 3, 2

Moving disk 1 from 2 to 3

L4, 1, 2, 3, 1
L0, 2, 1, 3, 2
Recursive call at L3, push()

L4, 0, 1, 3, 2
L4, 1, 2, 3, 1
L0, 2, 1, 3, 2
L4, 0, 1, 3, 2
L4, 1, 2, 3, 1
L0, 2, 1, 3, 2

Pop(), goto L4, so pop() again, goto L4
pop() again
Final state when
move(2, 1,3,2) is done
Recursion (递归）

1. Introduction to Recursion
-- Solving problems using recursion
-- Recursion trees
2. How recursion is implemented on the machine
-- Stacks and recursion
3. Analyzing Recursion
-- when to use recursion
4. Backtracking (回溯法）– a method to try all
possibilities using recursion
Analyzing space and time complexity

What correspond to time
complexity?
3 time units +
A’s and D’s time units

3
The time
complexity is
proportional to
the number of                  3
nodes.                                       2

1                     2

time complexity: count the
total time units in the
1
function call tree.
Complexity of factorial

递归工作栈占用空间 = O(n)

T(0) = 1
T(n)= 1 + T(n-1) = O(n)
(recurrence relation 递推关系）
Complexity of Hanoi

= O(n)           T(n) = O(2n)
Complexity and recursive trees

杂度和时间复杂度：
• 空间复杂度与递归树的高度成正比；
• 时间复杂度与函数的调用次数有关，与递
归树的结点总数正比。
• A recursive algorithm must have a base case, which gives a
direct solution, and a method which reduces general cases to
simpler cases.
• Recursion is done by using stacks:
– When a call is made, the activation record is pushed into the
stack and control is passed to the called function;
– When the call is finished, the activation record is popped off
the stack and execution starts from the address in the popped
record.
• The recursive tree of a recursive algorithm can be used to
analyze the algorithm:
– The space complexity is proportional to the height of the
recursive tree;
– The time complexity is proportional to the number of nodes.
Recursive or Nonrecursive
Factorials             Recursive version

Nonrecursive
version
The recursive version is
more expensive in space
and time
Recursion tree for F7                     F5 is repeated

F3 is repeated 5 times
Nonrecursive
version

Using Iteration
（迭代）
• Space complexity for recursive version is linear in n.
• Time complexity for the recursive version is
exponential with n (>= 2n/2).
• Time complexity for the nonrecursive version is linear
in n.
• The space complexity for the nonrecursive version: it
uses only 4 variables.
Hanoi with tail recursion

Last executed statement is a
recursive call
Hanoi without tail recursion
When to use recursion
• If time and space is not an issue, then
recursive version is much easier to understand
and preferred.
• If duplicate tasks are involved, then data
structure other than stacks will be appropriate.
• Recursion can always be replaced by iteration
and stacks. But no point to do it if not
necessary.
Recursion (递归）

1. Introduction to Recursion
-- Solving problems using recursion
-- Recursion trees
2. How recursion is implemented on the machine
-- Stacks and recursion
3. Analyzing Recursion
-- when to use recursion
4. Backtracking (回溯法）– a method to try all
possibilities using recursion
Backtracking(回溯）
A method to try all possibilities using recursion.

When there are several possibilities,
• take one and go on;
• go back to the most recent choice, and try another
possibility when a dead end is reached.
Eight Queens Puzzle
Four Queens Solution
Take 1 of the 4 legitimate positions

guarded

backtrack

backtrack
backtrack
Backtracking
• Backtracking is a recursive method that goes back to
the most recent choice and tries another possibility.
• In (b), we go back to row 2 and put the queen in
• In (c) , there is no other possibilities in row two. We go
back to row 1 and put the queen in column 2.
Outline of the solution

• Imagining using a class called Queens to represent a
partial configuration(格局, 状态） of queens;
• Add a queen in the configuration and continue the
search from the new configuration;
• If this does not lead to a solution, then remove the
newly added queens and try another position and
continue the search until a solution is reached.
Exit: a solution is
found

When it is returned here, the
queen added at p is removed
Exit: dead end   and try next possible position.
The main program
The Queen Class

(count, col) denotes a
possible position
The position is
empty
count is modified    Occupied
after insertion.
It is not necessary to check the lower
part. (?)
The Backtracking Function
Guarded positions are
not investigated

Effectively pruning
a recursion tree

Part of the recursion tree for eight queens problem
Analysis of Backtracking
• Effectiveness of backtracking: positions that are
discovered impossible prevent the later
investigation of fruitless paths.
• Number of configurations that there is only one
queen in each row: 88
• Number of configurations that there is only one
queen in each column: 8!
• Backtracking cut this number further: it does not
investigate impossible paths. See the recursion
tree.
Lower Bounds
However, the amount of work done by backtracking
still grows rapidly with n.
To place a queen on the first n/4 rows, the minimum
positions to investigate:
n(n-3)(n-6)…(n-3n/4) > (n/4)n/4 > 2n

The queen guards at most three
positions in the next row
• The loops in function unguarded takes
considerable time when checking if a position is
guarded in three directions.
• An improvement is to keep track which columns
are guarded using an one dimension bool array,
which diagonals are guarded using two bool
arrays. This make the function unguarded much
simpler.
Upward_free:
row+col:0--6

Downward_free:
board_size-1+row-col:0--6
New Queens

Number of
diagonals
Modify the column and two
diagonals that are guarded
now.
bool Queens::unguarded(int col)const
/*Post: Return true if the position (count, col)
is unguarded, false else. */
{
return col_free(col)
&& upward_free[count+col]
&& downward_free[count-col+board_size-1];
}
Summary
• Recursion: concept and recursion trees
• Principles of designing recursive algorithms;
• Divide and conquer, a method to solve problems
using recursion;
• How recursion is implemented in machine;
• Complexity analysis using recursion trees.

```
To top