KTLT.C4. Recursion
KTLT.C4. Recursion
Chapter 4
Recursion
2
Outlines
• Introduction
• The Data Hierarchy
• File Types
• Input /Output Streams
• Stream Headers, Templates and Classes
• File Streams
• File Modes
• Writing Data from a Text File
• Reading Data from a Text File
• Example
• Issues to expand career knowledge
3
4
5
• When faced with a difficult problem, a classic technique is to break it
down into smaller parts that can be solved more easily. Recursion is
one way to do this.
• In some cases, recursion is the best way to solve the problem.
▪ Examples: Define a tree data structure and traversal the tree (define Folder and
browse files in a folder), ..
• Recursion is a useful tool, but it can increase memory usage and
make debugging difficult.
6
• Define an entity in terms of itself. There are two parts:
▪ Base case (basis): the most primitive case(s) of the entity are
defined without reference to the entity.
▪ Recursive case (inductive) : new cases of the entity are defined
in terms of simpler cases of the entity.
• Examples:
▪ A recursive definition of exponentiation (an):
o a0 = 1 // base case
o an = (an-1)*a , for n > 0 // recursive cases (steps)
▪ Recursively defined data structures:
struct Node {
... ...
Node *Next;
};
7
• Many programs must process or generate an arbitrarily
large quantity of data. Recursion is one technique for
representing data whose exact size the programmers does
not know: the programmer can specify this data with a self-
referential definition.
• There are two types of self-referential definitions:
▪ Inductively defined data: is one that specifies how to construct
instances of the data. For example, Linked Lists can be defined
inductively.
• Coinductively defined data and corecursion: new is one
that specifies the operations that may be performed on a piece of
data; typically, self-referential coinductive definitions are used for
data structures of infinite size. For example, a stream of strings is an
object S such that: head(S) is a string, and tail(S) is a stream of strings.
8
• A sequence is an ordered list of objects, which is
potentially infinite. S(K) denotes Kth object in sequence.
• A sequence is defined recursively by explicitly naming the
first value (or the first few values) and then define later values
in the sequence in terms of earlier values.
• Examples:
▪ A recursively defined sequence:
o S(0) = 1 // base case
o S(n+1) = (n+1) * S(n), for n >= 0 // recursive case
what does the sequence look like?
▪ The Fibonacci Sequence is defined by:
o F(1) = 1, F(2) = 1 // base case
o F(n) = F(n-2) + F(n-1), for n > 2 // recursive case
9
If a recurrence relation exists for an operation, then the
algorithm can be written either iteratively or recursively.
recursive_algorithm(input) {
if ( isSmallEnough (input) ) // base-case
compute the solution and return it
else // recursive case
break input into simpler instances input1, input 2,...
solution1 = recursive_algorithm (input1)
solution2 = recursive_algorithm (input2)
...
figure out solution to this problem from solution1, solution2, ..
return solution
}
10
• A recursive implementation always has 2 parts:
▪ Base case: the simplest, smallest instance of the problem, that
can’t be decomposed any further. Base cases often correspond to
emptiness: empty string, empty list, empty set, empty tree, zero,..
• Recursive step: decomposes a larger instance into one or more
simpler or smaller instances that can be solved by recursive calls
(to this same function, but with the inputs somehow reduced in
size or complexity, closer to a base case), and then recombines
the results of those subproblems to produce the solution to the
original problem.
[ may be more than one base case or more than one recursive step ]
• Helper function: it is a way to reduce complexity within
other functions. In some cases, it’s useful to require a
stronger specification for the recursive steps, to make the
recursive decomposition simpler or more elegant 11
Factorial S(n) = n! = 1*2*3*...*(n-1)*n can be defined
recursively as follows:
▪ S(0) = 1,
▪ S(n) = n*S(n-1) for n >= 1
iteratively recursively
long factorial(int n) { long factorial(int n) {
long f = 1; if (n == 0) // base case
for (int i=2; i<n; ++i) return 1;
f *= i; //else // recursive case
return f; return n* factorial(n-1);
} }
12
void main() { long x = factorial (3); }
13
The Fibonacci Sequence is defined by:
o F(1) = 1, F(2) = 1 // base case
o F(n) = F(n-2) + F(n-1), for n > 2 // recursive case
14
S(n) = 1/2 + 2/3 + 3/4 + ... + n/(n+1)
o S(0) = 0 // base case
o S(n) = S(n-1) + n/(n+1) , for n > 0 // recursive case
15
o Even: (n = 0) or (n-1 is Odd)
o Odd: (n==1) or (n-1 is Even)
[ Indirect Recursion ] [ Đệ quy Hỗ tương ]
bool isEven (unsigned n) { bool isOdd (unsigned n) {
if (n == 0) // base case if (n == 1) // base case
return true; return true;
//else // recursive case
//else // recursive case
return isOdd (n-1);
} return isEven (n-1);
}
16
S(n)=sqrt(2021+sqrt(2021+....+sqrt(2021+sqrt(2021))))
// n dấu cộng
▪ S(0) = sqrt (2021) // base case
▪ S(n) = sqrt (2021 + S(n-1)) // recursive case
Recursive Algorithm Square Root [ Nested Recursion / Đệ quy lồng ]
recursive_function(input) {
if ( isSmallEnough (input) ) // base-case double SquareRoot (int n) {
compute the solution and return it
else // recursive case if (n == 0) // base case
break input into simpler instances input1, input 2,... return sqrt(2021);
solution1 = recursive_function (input1) //else // recursive case
solution2 = recursive_function (input2)
...
return sqrt(2021+ SquareRoot(n-1) );
figure out solution to this problem from solution1, 2,.. }
return solution
}
17
• Recursion are mainly of 2 types depending on whether a
function calls itself from within itself or more than one
function call one another mutually. They are called Direct
Recursion and Indirect Recursion.
• In another common classification, there are 2 types: Single
Recursion and Multiple Recursion, when while recursion
that contains single or multiple self-references
• Single Recursion (Linear Recursion) includes Tail Recursion
and Head Recursion (If a recursive function calling itself and
that recursive call is the last /first statement in the function).
• Multiple Recursion (Tree Recursion) : If a recursive function
calling itself for more than one time.
• A special kind - Nested Recursion: a recursive function
will pass the parameter as a recursive call. That
means “recursion inside recursion” 18