A, i, n

Seminar 4
IT310 Data Structures and
Algorithms ( in Java)
Instructor : Vladimir Gubanov, PhD
Email : [email protected]
AIM : vladimirg77
Data Structures and Algorithms in Java
Stacks , Queues and
Recursion
Data Structures and Algorithms in Java
Abstract Data Types (ADTs)


An abstract data
type (ADT) is an
abstraction of a
data structure
An ADT specifies:



Data stored
Operations on the
data
Error conditions
associated with
operations

Example: ADT modeling a
simple stock trading system


The data stored are buy/sell
orders
The operations supported are
 order buy(stock, shares, price)
 order sell(stock, shares, price)
 void cancel(order)

Error conditions:
 Buy/sell a nonexistent stock
 Cancel a nonexistent order
Abstract data types allow to delay the specific implementation of a data type until it is
Stacks on the data. Only after the list of the
understood what operations are required to operate
3
Stacks
Stacks
4
What is a stack?
•
•
It is an ordered group of homogeneous items of elements.
Elements are added to and removed from the top of the
stack (the most recently added items are at the top of the
stack).
Stacks
• A stack is a linear data structure that can be
accessed only at one of its ends for storing
and retrieving data
• A stack is called an LIFO structure: last in/first
out
Data Structures and Algorithms in Java
6
The Stack ADT




The Stack ADT stores
arbitrary objects
Insertions and deletions
follow the last-in firstout scheme
Think of a spring-loaded
plate dispenser
Main stack operations:


push(object): inserts an
element
object pop(): removes and
returns the last inserted
element
Stacks

Auxiliary stack
operations:



object top(): returns the
last inserted element
without removing it
integer size(): returns the
number of elements
stored
boolean isEmpty():
indicates whether no
elements are stored
7
Push (ItemType newItem)
• Function: Adds newItem to the top of
the stack.
• Preconditions: Stack has been
initialized and is not full.
• Postconditions: newItem is at the top
of the stack.
Pop (ItemType& item)
• Function: Removes topItem from stack and
returns it in item.
• Preconditions: Stack has been initialized
and is not empty.
• Postconditions: Top element has been
removed from stack and item is a copy of
the removed element.
Stacks (continued)
Figure 4-1 A series of operations executed on a stack
Generally, the stack is very useful in situations when data
have to be stored and then retrieved in reverse order.
Data Structures and Algorithms in Java
11
Stack Interface in Java



public interface Stack<E> {
Java interface
corresponding to
public int size();
our Stack ADT
public boolean isEmpty();
Requires the
public E top()
definition of class
throws EmptyStackException;
EmptyStackException
public void push(E element);
Different from the
built-in Java class
public E pop()
java.util.Stack
throws EmptyStackException;
}
Stacks
12
Exceptions


Attempting the
execution of an
operation of ADT may
sometimes cause an
error condition, called
an exception
Exceptions are said to
be “thrown” by an
operation that cannot
be executed
© 2010 Goodrich, Tamassia
Stacks


In the Stack ADT,
operations pop and
top cannot be
performed if the
stack is empty
Attempting the
execution of pop or
top on an empty
stack throws an
EmptyStackException
13
Applications of Stacks

Direct applications




Page-visited history in a Web browser
Undo sequence in a text editor
Chain of method calls in the Java Virtual
Machine
Indirect applications


Auxiliary data structure for algorithms
Component of other data structures
© 2010 Goodrich, Tamassia
Stacks
14
Method Stack in the JVM




The Java Virtual Machine (JVM) keeps
track of the chain of active methods with
a stack. Each JVM thread has a Java stack
containing all currently active
methods(only one method can be active –
others are suspended)
When a method is called, the JVM
pushes on the stack a frame containing
 Local variables and return value
 Program counter, keeping track of the
statement being executed
When a method ends, its frame is
popped from the stack and control is
passed to the method on top of the stack
Each method frame includes and
operand stack (source of arguments
and repository of results)
© 2010 Goodrich, Tamassia
Stacks
main() {
int i = 5;
foo(i);
}
foo(int j) {
int k;
k = j+1;
bar(k);
}
bar(int m) {
…
}
bar
PC = 1
m=6
foo
PC = 3
j=5
k=6
main
PC = 2
i=5
15
Array-based Stack



A simple way of
implementing the
Stack ADT uses an
array
We add elements
from left to right
A variable keeps
track of the index of
the top element
Algorithm size()
return t + 1
Algorithm pop()
if isEmpty() then
throw EmptyStackException
else
tt1
return S[t + 1]
…
S
0 1 2
t
Stack methods have to be implemented. Flexible array can be used (p.146 of your textbook). When
© 2010
Goodrich,
16
the stack
exceeds
theTamassia
initial size of the array – aStacks
copy to a larger array is created.
Array-based Stack (cont.)


The array storing the
stack elements may
become full
A push operation will
then throw a
FullStackException


Algorithm push(o)
if t = S.length  1 then
throw FullStackException
else
tt+1
Limitation of the arrayS[t]  o
based implementation
Not intrinsic to the
Stack ADT
…
S
0 1 2
© 2010 Goodrich, Tamassia
t
Stacks
17
Performance and Limitations

Performance




Let n be the number of elements in the stack
The space used is O(n)
Each operation (popping and pushing) is executed
in the constant time O(1)
Limitations


The maximum size of the stack is defined a
priori and cannot be changed without
copying to a larger array (O(n) then)
Trying to push a new element into a full stack
causes an implementation-specific exception
© 2010 Goodrich, Tamassia
Stacks
18
Other Implementations of Stack



Can be implemented in ArrayList
Can be implemented in Linked List
Implementation:




Includes creating and proper object (of above)
Defining pop(), push(), isEmpty(), topEl(),
clear() methods
see p. Fig 4.4 (p.146) of the textbook for ArrayList
( in next two slides) , Fig 4.5 (p.147) for Linked
List
No need to define the stack size in advance
Stacks
19
ArrayList Stack Implementation
Figure 4-4 Array list implementation of a stack
Data Structures and Algorithms in Java
20
Stacks (continued)
Figure 4-4 Array list implementation of a stack (continued)
Data Structures and Algorithms in Java
21
HTML Tag Matching
For fully-correct HTML, each <name> should pair with a matching </name>
<body>
<center>
<h1> The Little Boat </h1>
</center>
<p> The storm tossed the little
boat like a cheap sneaker in an
old washing machine. The three
drunken fishermen were used to
such treatment, of course, but
not the tree salesman, who even as
a stowaway now felt that he
had overpaid for the voyage. </p>
<ol>
<li> Will the salesman die? </li>
<li> What color is the boat? </li>
<li> And what about Naomi? </li>
</ol>
</body>
© 2010 Goodrich, Tamassia
The Little Boat
The storm tossed the little boat
like a cheap sneaker in an old
washing machine. The three
drunken fishermen were used to
such treatment, of course, but not
the tree salesman, who even as
a stowaway now felt that he had
overpaid for the voyage.
1. Will the salesman die?
2. What color is the boat?
3. And what about Naomi?
Stacks
22
Evaluating Arithmetic
Expressions
14 – 3 * 2 + 7 = (14 – (3 * 2) ) + 7
Operator precedence
* has precedence over +/–
Associativity
operators of the same precedence group
evaluated from left to right
Example: (x – y) + z rather than x – (y + z)
Idea: push each operator on the stack, but first pop and
perform higher and equal precedence operations.
Stacks
23
Quadratic Algorithm
Algorithm spans1(X, n)
Input array X of n integers
Output array S of spans of X
S  new array of n integers
for i  0 to n  1 do
s1
while s  i  X[i  s]  X[i]
ss+1
S[i]  s
return S
#
n
n
n
1 + 2 + …+ (n  1)
1 + 2 + …+ (n  1)
n
1
Algorithm spans1 runs in O(n2) time
© 2010 Goodrich, Tamassia
Stacks
24
Linear Algorithm
Each index of the
array


Is pushed into the
stack exactly one
Is popped from
the stack at most
once
The statements in
the while-loop are
executed at most
n times
Algorithm spans2
runs in O(n) time
© 2010 Goodrich, Tamassia
Algorithm spans2(X, n)
#
S  new array of n integers n
A  new empty stack
1
for i  0 to n  1 do
n
while (A.isEmpty() 
X[A.top()]  X[i] ) do n
A.pop()
n
if A.isEmpty() then
n
S[i]  i + 1
n
else
S[i]  i  A.top()
n
A.push(i)
n
return S
1
Stacks
25
Stacks in java.util package


Available as generic stack – extension
of Vector class
Can be created and initialized as :
java.util.Stack stack = new java.util.Stack();


Has five methods ( empty(), peek(),
pop(), push(Object el), search(Object
el), Stack()
Elements can be accessed not at one
end only – violation of stack integrity
© 2010 Goodrich, Tamassia
Stacks
26
Stacks in java.util
Figure 4-7 A list of methods in java.util.Stack; all methods from
Vector are inherited
Data Structures and Algorithms in Java
27
Queues
© 2010 Goodrich, Tamassia
28
Queues
What is a queue?
• It is an ordered group of homogeneous items of
•
elements.
Queues have two ends:
– Elements are added at one end.
– Elements are removed from the other end.
• The element added first is also removed first
(FIFO: First In, First Out).
queue
tail
elements
enter
4
3
head
2
1
no changes of order
elements
exit
Queues
• A queue is a waiting line that grows by adding
elements to its end and shrinks by taking
elements from its front
• A queue is a structure in which both ends are
used:
– One for adding new elements
– One for removing them
• A queue is an FIFO structure: first in/first out
Data Structures and Algorithms in Java
30
Queue Operations
• The following operations are needed to properly
manage a queue:
– clear() — Clear the queue
– isEmpty() — Check to see if the queue is empty
– enqueue(el) — Put the element el at the end of
the queue
– dequeue() — Take the first element from the
queue
– firstEl() — Return the first element in the queue
without removing it
Data Structures and Algorithms in Java
31
Queue Specification
• Definitions:
(provided by the user)
– MAX_ITEMS: Max number of items that might be on
the queue
– ItemType: Data type of the items on the queue
• Operations
–
–
–
–
–
MakeEmpty
Boolean IsEmpty
Boolean IsFull
Enqueue (ItemType newItem)
Dequeue (ItemType& item) (serve and retrieve)
The Queue ADT




The Queue ADT stores arbitrary  Auxiliary queue
objects
operations:
Insertions and deletions follow
 object front(): returns the
element at the front without
the first-in first-out scheme
removing it
Insertions are at the rear of the
 integer size(): returns the
queue and removals are at the
number of elements stored
front of the queue
 boolean isEmpty(): indicates
Main queue operations:
whether no elements are
 enqueue(object): inserts an
stored

element at the end of the

queue
object dequeue(): removes
and returns the element at the
front of the queue
© 2010 Goodrich, Tamassia
Queues
Exceptions

Attempting the execution of
dequeue or front on an
empty queue throws an
EmptyQueueException
33
Enqueue (ItemType newItem)
• Function: Adds newItem to the rear of the
queue.
• Preconditions: Queue has been initialized
and is not full.
• Postconditions: newItem is at rear of queue.
Dequeue (ItemType& item)
• Function: Removes front item from queue
and returns it in item.
• Preconditions: Queue has been initialized
and is not empty.
• Postconditions: Front element has been
removed from queue and item is a copy of
removed element.
Queues (continued)
Figure 4-8 A series of operations executed on a queue
In the difference from Stack, changes need to be monitored at the
beginning of the queue and at the end : elements are engueued on one
end (right above) and dequeued on the other ( left above).
Data Structures and Algorithms in Java
36
Annother Example
Operation
enqueue(5)
enqueue(3)
dequeue()
enqueue(7)
dequeue()
front()
dequeue()
dequeue()
isEmpty()
enqueue(9)
enqueue(7)
size()
enqueue(3)
enqueue(5)
dequeue()
© 2010 Goodrich, Tamassia
–
–
5
–
3
7
7
“error”
–
–
2
–
–
9
Output Q
(5)
(5, 3)
(3)
(3, 7)
(7)
(7)
()
()
true
()
(9)
(9, 7)
(9, 7)
(9, 7, 3)
(9, 7, 3, 5)
(7, 3, 5)
Queues
37
Applications of Queues

Direct applications




Waiting lists, bureaucracy
Access to shared resources (e.g., printer)
Multiprogramming
Indirect applications


Auxiliary data structure for algorithms
Component of other data structures
Again, queue can be implemented
based
on Array, ArrayList,
Linked List
© 2010 Goodrich,
Tamassia
Queues

38
Array-based Queue


Use an array of size N in a circular fashion
Two variables keep track of the front and rear
f index of the front element
r index immediately past the rear element

Array location r is kept empty
normal configuration
Q
0 1 2
f
r
wrapped-around configuration
Q
0 1 2
r
f
Queue
is full
when Tamassia
the first element is in Queues
the first cell or the last element is in the last
© 2010
Goodrich,
39
cell , or the first element is right after the last
Figure 4-9 Two possible configurations in an array implementation
of a queue when the queue is full
Data Structures and Algorithms in Java
40
Queue Operations

We use the
modulo operator
(remainder of
division)
Algorithm size()
return (N  f + r) mod N
Algorithm isEmpty()
return (f = r)
Q
0 1 2
f
0 1 2
r
r
Q
f
Java code implementation of Queue based on Array – see Fig
© 2010 Goodrich, Tamassia
Queues
41
4.10 of the textbook ; on Linked List – Fig.4.11 ( p.153)
Queue Operations (cont.)


Operation enqueue
throws an exception if
the array is full
This exception is
implementationdependent
Algorithm enqueue(o)
if size() = N  1 then
throw FullQueueException
else
Q[r]  o
r  (r + 1) mod N
Q
0 1 2
f
0 1 2
r
r
Q
© 2010 Goodrich, Tamassia
f
Queues
42
Queue Operations (cont.)


Operation dequeue
throws an exception
if the queue is empty
This exception is
specified in the
queue ADT
Algorithm dequeue()
if isEmpty() then
throw EmptyQueueException
else
o  Q[f]
f  (f + 1) mod N
return o
Q
0 1 2
f
0 1 2
r
r
Q
f
In ©
both
Array and Linked List implementation
– enqueueing and
2010 Goodrich, Tamassia
Queues
dequeueing operations are executed in constant time O(1)
43
Queue Interface in Java



Java interface
corresponding to
our Queue ADT
Requires the
definition of class
EmptyQueueException
No
corresponding
built-in Java
class
© 2010 Goodrich, Tamassia
public interface Queue<E> {
public int size();
public boolean isEmpty();
public E front()
throws EmptyQueueException;
public void enqueue(E element);
public E dequeue()
throws EmptyQueueException;
}
Queues
44
Applications: Round Robin Schedulers
We can implement a round robin scheduler using a
queue Q by repeatedly performing the following
steps:

1.
2.
3.
e = Q.dequeue()
Service element e
Q.enqueue(e)
Queue
Dequeue
Enqueue
Shared
Service
© 2010 Goodrich, Tamassia
Queues
45
Priority Queues
• Simple queues are inadequate when first in/first
out scheduling has to be overruled using some
priority criteria ( e.g. a handicapped person may
have priority over others in a post office line)
• A priority queue can be assigned to enable a
particular process, or event, to be executed out
of sequence without affecting overall system
operation
• In priority queues, elements are dequeued
according to their priority and their current
queue position
Data Structures and Algorithms in Java
46
Priority Queues (continued)
• Priority queues can be represented by two
variations of linked lists:
– in one type : all elements are entry ordered
– in another : order is maintained by putting a new
element in its proper position according to its
priority
• Total operational times are usually O(n)
Data Structures and Algorithms in Java
47
Summary
• A stack is a linear data structure that can be
accessed at only one of its ends for storing
and retrieving data.
• A stack is called an LIFO structure: last in/first
out.
• A queue is a waiting line that grows by adding
elements to its end and shrinks by taking
elements from its front.
• A queue is an FIFO structure: first in/first out.
Data Structures and Algorithms in Java
48
Summary (continued)
• In queuing theory, various scenarios are
analyzed and models are built that use queues
for processing requests or other information in
a predetermined sequence (order).
• A priority queue can be assigned to enable a
particular process, or event, to be executed out
of sequence without affecting overall system
operation.
Data Structures and Algorithms in Java
49
Summary (continued)
• In priority queues, elements are dequeued
according to their priority and their current
queue position.
Data Structures and Algorithms in Java
50
Programming with Recursion
© 2010 Goodrich, Tamassia
Programming with Recursion
51
Recursive Definitions
• Recursive definitions are programming
concepts that define themselves
• A recursive definition consists of two parts:
– The anchor or ground case, the basic elements that
are the building blocks of all other elements of the set
are listed
– Rules that allow for the construction of new objects
out of basic elements or objects that have already
been constructed; these rules are applied again and
again to generate new objects
– Recursive definitions serve two purposes: generating
new elements, and testing whether an element
Data Structures
and to
Algorithms
52
belongs
a set.in Java
The Recursion Pattern



Recursion: when a method calls itself
Classic example: the factorial function:
n! = 1· 2· 3· ··· · (n1)· n
Recursive definition:
if n = 0
 1
f ( n) = 
n  f (n  1) else

Definition above can be easily converted into a Java
method:
// recursive factorial function
public static int recursiveFactorial(int n) {
if (n == 0) return 1; // basis case
else return n * recursiveFactorial(n- 1); // recursive case
}
53
Content of a Recursive Method



Base case(s)
 Values of the input variables for which we perform no
recursive calls are called base cases (there should be at
least one base case).
 Every possible chain of recursive calls must eventually reach
a base case.
Recursive calls
 Calls to the current method.
 Each recursive call should be defined so that it makes
progress towards a base case.
Recursion is calling a method that happens to have the same
name as the caller. A recursive call is not literally a method
calling itself, but rather an instantiation of a method calling
another instantiation of the same original.
Programming with Recursion
© 2010 Goodrich, Tamassia
54
Using Recursion
© 2010 Goodrich, Tamassia
Using Recursion
55
Linear Recursion

Test for base cases



Begin by testing for a set of base cases (there should be
at least one).
Every possible chain of recursive calls must eventually
reach a base case, and the handling of each base case
should not use recursion.
Recur once



Perform a single recursive call
This step may have a test that decides which of several
possible recursive calls to make, but it should ultimately
make just one of these calls
Define each possible recursive call so that it makes
progress towards a base case.
© 2010 Goodrich, Tamassia
Using Recursion
56
Example of Linear Recursion
Example recursion trace:
Algorithm LinearSum(A, n):
Input:
A integer array A and an
integer n = 1, such that A
has at least n elements
call
LinearSum (A,5)
Output:
call
return 13 + A[3] = 13 + 2 = 15
LinearSum (A,4)
The sum of the first n
integers in A
call
return 7 + A[2] = 7 + 6 = 13
LinearSum (A,3)
if n = 1 then
return A[0]
else
return LinearSum(A, n - 1) +
A[n - 1]
© 2010 Goodrich, Tamassia
return 15 + A[4] = 15 + 5 = 20
Using Recursion
call
return 4 + A[1] = 4 + 3 = 7
LinearSum (A,2)
call
return A[0] = 4
LinearSum (A,1)
57
Reversing an Array
Algorithm ReverseArray(A, i, j):
Input: An array A and nonnegative integer
indices i and j
Output: The reversal of the elements in A
starting at index i and ending at j
if i < j then
Swap A[i] and A[ j]
ReverseArray(A, i + 1, j - 1)
return
© 2010 Goodrich, Tamassia
Using Recursion
58
Defining Arguments for Recursion



In creating recursive methods, it is important
to define the methods in ways that
facilitate recursion.
This sometimes requires we define additional
paramaters that are passed to the method.
For example, we defined the array reversal
method as ReverseArray(A, i, j), not
ReverseArray(A).
© 2010 Goodrich, Tamassia
Using Recursion
59
Computing Powers

The power function, p(x,n)=xn, can be
defined recursively:
1
if n = 0

p( x, n) = 
 x  p( x, n  1) else


This leads to an power function that runs in
O(n) time (for we make n recursive calls).
We can do better than this, however.
© 2010 Goodrich, Tamassia
Using Recursion
60
Recursive Squaring

We can derive a more efficient linearly
recursive algorithm by using repeated
squaring:
1
if x = 0


p( x, n) =  x  p( x, (n  1) / 2) 2
2

p
(
x
,
n
/
2
)


if x  0 is odd
if x  0 is even
For example,
24 = 2(4/2)2 = (24/2)2 = (22)2 = 42 = 16
25 = 21+(4/2)2 = 2(24/2)2 = 2(22)2 = 2(42) = 32
26 = 2(6/ 2)2 = (26/2)2 = (23)2 = 82 = 64
27 = 21+(6/2)2 = 2(26/2)2 = 2(23)2 = 2(82) = 128.
© 2010 Goodrich, Tamassia
Using Recursion
61
Recursive Squaring Method
Algorithm Power(x, n):
Input: A number x and integer n = 0
Output: The value xn
if n = 0 then
return 1
if n is odd then
y = Power(x, (n - 1)/ 2)
return x · y ·y
else
y = Power(x, n/ 2)
return y · y
© 2010 Goodrich, Tamassia
Using Recursion
62
Analysis
Algorithm Power(x, n):
Input: A number x and
integer n = 0
Output: The value xn
if n = 0 then
return 1
if n is odd then
y = Power(x, (n - 1)/ 2)
return x · y · y
else
y = Power(x, n/ 2)
return y · y
© 2010 Goodrich, Tamassia
Using Recursion
Each time we make a
recursive call we halve
the value of n; hence,
we make log n recursive
calls. That is, this
method runs in O(log n)
time.
It is important that we
use a variable twice
here rather than
calling the method
twice.
63
Tail Recursion



All recursions contain a reference to a
set or function to be defined
Can be implemented in different ways
Tail recursion is using only one
recursive call at the very end of method
implementation – when a call is made ,
there is no statements left to execute in
that method
© 2010 Goodrich, Tamassia
Stacks
64
Tail Recursion Example

Tail recursion is characterized by the
use of only one recursive call at the
very end of a method implementation
void tail (int i) {
if (i > 0) {
System.out.print (i + "");
tail(i-1);
}
}
65
Tail recursion can be easily replaced by a loop ( see p.179)
NonTail Recursion Example
Example of nontail recursion:
void nonTail (int i) {
if (i > 0) {
nonTail(i-1);
System.out.print (i + "");
nonTail(i-1);
}
}
66
Tail Recursion




Tail recursion occurs when a linearly recursive
method makes its recursive call as its last step.
The array reversal method is an example.
Such methods can be easily converted to nonrecursive methods (which saves on some resources).
Example:
Algorithm IterativeReverseArray(A, i, j ):
Input: An array A and nonnegative integer indices i and j
Output: The reversal of the elements in A starting at
index i and ending at j
while i < j do
Swap A[i ] and A[ j ]
i =i+1
j =j-1
return
© 2010 Goodrich, Tamassia
Using Recursion
67
Indirect and Nested Recursion


Direct recursion - a method calls itself
Indirect recursion - a method calls itself
via a chain of other calls :
f() -> f1() -> f2() -> · · · -> fn() -> f()

A function is defined in terms of itself
and used as one of its parameters:
0 if n=0
h(n) = { n if n>4
h(2 + h(2n) if n< 4
68
Binary Recursion


Binary recursion occurs whenever there are two
recursive calls for each non-base case.
Example: the DrawTicks method for drawing
ticks on an English ruler.
© 2010 Goodrich, Tamassia
Using Recursion
69
A Binary Recursive Method for
Drawing Ticks
// draw a tick with no label
public static void drawOneTick(int tickLength) { drawOneTick(tickLength, - 1); }
// draw one tick
public static void drawOneTick(int tickLength, int tickLabel) {
for (int i = 0; i < tickLength; i++)
System.out.print("-");
if (tickLabel >= 0) System.out.print(" " + tickLabel);
Note the two
System.out.print("\n");
recursive calls
}
public static void drawTicks(int tickLength) { // draw ticks of given length
if (tickLength > 0) {
// stop when length drops to 0
drawTicks(tickLength- 1);
// recursively draw left ticks
drawOneTick(tickLength);
// draw center tick
drawTicks(tickLength- 1);
// recursively draw right ticks
}
}
public static void drawRuler(int nInches, int majorLength) { // draw ruler
drawOneTick(majorLength, 0); // draw tick 0 and its label
for (int i = 1; i <= nInches; i++)
{
drawTicks(majorLength- 1); // draw ticks for this inch
drawOneTick(majorLength, i);
// draw tick i and its label
}
}
© 2010 Goodrich, Tamassia
Using Recursion
70
Another Binary Recusive Method

Problem: add all the numbers in an integer array A:
Algorithm BinarySum(A, i, n):
Input: An array A and integers i and n
Output: The sum of the n integers in A starting at index i
if n = 1 then
return A[i ]
return BinarySum(A, i, n/ 2) + BinarySum(A, i + n/ 2, n/ 2)

Example trace:
0, 8
0, 4
4, 4
0, 2
0, 1
2, 2
1, 1
© 2010 Goodrich, Tamassia
2, 1
4, 2
3, 1
4, 1
Using Recursion
6, 2
5, 1
6, 1
7, 1
71
Computing Fibonacci Numbers

Fibonacci numbers are defined recursively:
F0 = 0
F1 = 1
Fi = Fi-1 + Fi-2

for i > 1.
Recursive algorithm (first attempt):
Algorithm BinaryFib(k):
Input: Nonnegative integer k
Output: The kth Fibonacci number Fk
if k = 1 then
return k
else
return BinaryFib(k - 1) + BinaryFib(k - 2)
© 2010 Goodrich, Tamassia
Using Recursion
72
Analysis

Let nk be the number of recursive calls by BinaryFib(k)











n0 = 1
n1 = 1
n2 = n1 + n0 + 1 = 1 + 1 + 1 = 3
n3 = n2 + n1 + 1 = 3 + 1 + 1 = 5
n4 = n3 + n2 + 1 = 5 + 3 + 1 = 9
n5 = n4 + n3 + 1 = 9 + 5 + 1 = 15
n6 = n5 + n4 + 1 = 15 + 9 + 1 = 25
n7 = n6 + n5 + 1 = 25 + 15 + 1 = 41
n8 = n7 + n6 + 1 = 41 + 25 + 1 = 67.
Note that nk at least doubles every other time
That is, nk > 2k/2. It is exponential!
© 2010 Goodrich, Tamassia
Using Recursion
73
A Better Fibonacci Algorithm

Use linear recursion instead
Algorithm LinearFibonacci(k):
Input: A nonnegative integer k
Output: Pair of Fibonacci numbers (Fk , Fk1)
if k = 1 then
return (k, 0)
else
(i, j) = LinearFibonacci(k  1)
return (i +j, i)

LinearFibonacci makes k1 recursive calls
© 2010 Goodrich, Tamassia
Using Recursion
74
Multiple Recursion

Motivating example:

summation puzzles
 pot + pan = bib
 dog + cat = pig
 boy + girl = baby

Multiple recursion:


makes potentially many recursive calls
not just one or two
© 2010 Goodrich, Tamassia
Using Recursion
75
Algorithm for Multiple Recursion
Algorithm PuzzleSolve(k,S,U):
Input: Integer k, sequence S, and set U (universe of elements to
test)
Output: Enumeration of all k-length extensions to S using elements
in U without repetitions
for all e in U do
Remove e from U
{e is now being used}
Add e to the end of S
if k = 1 then
Test whether S is a configuration that solves the puzzle
if S solves the puzzle then
return “Solution found: ” S
else
PuzzleSolve(k - 1, S,U)
Add e back to U
{e is now unused}
Remove e from the end of S
© 2010 Goodrich, Tamassia
Using Recursion
76
Summary
• Recursive definitions are programming
concepts that define themselves
• Recursive definitions serve two purposes:
– Generating new elements
– Testing whether an element belongs to a set
• Recursive definitions are frequently used to
define functions and sequences of numbers
Data Structures and Algorithms in Java
77
Summary (continued)
• Tail recursion is characterized by the use of only one
recursive call at the very end of a method
implementation.
• No general rules for when to use it and when to use it.
Each particular problem decides.
• Recursion is usually less efficient than its iterative
equivalent.
• Recursion is often simpler than the iterative solution
• Every recursive method can be converted into an
iterative version
• Sometimes a recursive version is faster than a
nonrecursive implementation.
Data Structures and Algorithms in Java
78
Quck Quiz
1. What is a recursion ?
2. Can a recursion do something which iteration
cannot ?
3. Can a recursion take less coding than iteration?
4. : Does using recursion usually make your code
faster?
5. Does using recursion usually use less
memory?
6. Then why use recursion?
Data Structures and Algorithms in Java
79
Quite a number of good sites on
recursion are available on the WEB - below
are just some :
http://cplus.about.com/od/glossar1/g/recursiondefn.htm
http://www.sharpened.net/glossary/definition.php?recursive
function
and many more.
Recursion might look unusual and confusing at first, but it
serves well in many cases...
Data Structures and Algorithms in Java
80