Professional Documents
Culture Documents
Applied Programming (Recursion, Searching, Sorting) : National University of Computer & Emerging Sciences
Applied Programming (Recursion, Searching, Sorting) : National University of Computer & Emerging Sciences
Applied Programming (Recursion, Searching, Sorting) : National University of Computer & Emerging Sciences
School of Computing
National University of Computer & Emerging Sciences ,
Islamabad Campus
Recursion
Introduction to Recursion
• A recursive function is one that calls itself.
void Message(void)
{
cout << "This is a recursive function.\n";
Message();
}
Value of times: 3
Value of times: 2
• Indirect recursion
– function A calls function B, and function B calls
function A. Or,
14-11
Recursive Function
#include <iostream>
using namespace std;
void message(int);
int main()
{ message(5);
return 0; message called with 5 in times.
}
This is a recursive function.
//************************************************************message called with 4 in times.
// Definition of function message. If the value in times is *
// greater than 0, the message is displayed and the function *This is a recursive function.
// is recursively called with the argument times - 1. *
//************************************************************message called with 3 in times.
This is a recursive function.
void message(int times)
{ cout << "message called with " << times message called with 2 in times.
<< " in times.\n";
This is a recursive function.
if (times > 0)
{ message called with 1 in times.
cout << "This is a recursive function.\n";
This is a recursive function.
message(times - 1);
} message called with 0 in times.
14-13
The Recursive Factorial Function
• Factorial of n can be expressed in terms of the factorial of n-1
0!=1
n ! = n x (n-1) !
• The base case is n = 0
• Recursive function:
int factorial(int n)
{
if (n == 0)
return 1;
else
return n * factorial(n-1);
} 14-14
Character count - Recursive
#include <iostream> search, char str[], int subscript)
int numChars(char
using namespace std;
{
// Function prototype
int if (str[subscript] == '\0')
numChars(char, char [], int);
{
int main()
{ // Base case: The end of the string is reached.
char array[] = "abcddddef";
return 0;
/* Display the number of times the letter
} appears in the string. */
'd'
else if (str[subscript] == search)
cout << "The letter d appears "
<<
{ numChars('d', array, 0) << " times.\n";
/* Recursive
return 0; case: A matching character was found. Return
} 1 plus the number of times the search character appears in the
rest of the string.*/
14-15
return 1 + numChars(search, str,subscript+1);
Finding gcd
14-16
The Recursive gcd Function
int gcd(int x, int y)
{
if (x % y == 0) //base case
return y;
else
return gcd(y, x % y);
}
14-17
Solving Recursively Defined Problems
• The natural definition of some problems leads to a
recursive solution
• Recursive solution:
fib(n) = fib(n – 1) + fib(n – 2);
14-21
Recursion VS. Iteration
• Benefits (+), disadvantages(-) for recursion:
+ Natural formulation of solution to certain problems
+ Results in shorter, simpler functions
– May not execute very efficiently
14-31
Searching
Searching
• Given a collection and an element (key) to find…
• Output
– Print a message (“Found”, “Not Found”)
– Return a value (position of key )
i = 1
loop
exitif((i > MAX_ELEMENTS) OR (my_array[i] =
target))
i = i + 1
endloop
endprocedure // Search
my_array
7 12 5 22 13 32
target = 13 1 2 3 4 5 6
procedure Search(my_array isoftype in NumArrayType,
target isoftype in Num)
i = 1
loop
exitif((i > MAX) OR (my_array[i] = target))
i = i + 1
endloop
endprocedure // Search
my_array
7 12 5 22 13 32
target = 13 1 2 3 4 5 6
procedure Search(my_array isoftype in NumArrayType,
target isoftype in Num)
i = 1
loop
exitif((i > MAX) OR (my_array[i] = target))
i = i + 1
endloop
endprocedure // Search
my_array
7 12 5 22 13 32
target = 13 1 2 3 4 5 6
procedure Search(my_array isoftype in NumArrayType,
target isoftype in Num)
i = 1
loop
exitif((i > MAX) OR (my_array[i] = target))
i = i + 1
endloop
endprocedure // Search
my_array
7 12 5 22 13 32
target = 13 1 2 3 4 5 6
procedure Search(my_array isoftype in NumArrayType,
target isoftype in Num)
i = 1
loop
exitif((i > MAX) OR (my_array[i] = target))
i = i + 1
endloop
endprocedure // Search
my_array
7 12 5 22 13 32
target = 13 1 2 3 4 5 6
procedure Search(my_array isoftype in NumArrayType,
target isoftype in Num)
i = 1
loop
exitif((i > MAX) OR (my_array[i] = target))
i = i + 1
endloop
my_array
7 12 5 22 13 32
target = 13 1 2 3 4 5 6
procedure Search(my_array isoftype in NumArrayType,
target isoftype in Num)
i = 1
loop
exitif((i > MAX) OR (my_array[i] = target))
i = i + 1Target data found
endloop
my_array
7 12 5 22 13 32
target = 13 1 2 3 4 5 6
Linear Search Analysis: Best Case
pr oc e dur e Se a r c h( my_ ar r ay Ar r a y,
t ar ge t Num)
i Num
i <- 1 S c an the array
l o op
e xi t i f ( ( i > MAX) OR ( my_ ar r ay [ i ] = t ar ge t ) )
i <- i + 1
e ndl oo p
Best Case:
i f ( i > MAX) t he n
pr i nt ( “Tar ge t dat a not f ound”) 1 comparison
el s e
pr i nt ( “Tar ge t dat a f ound”)
e ndi f
e ndpr oc e dur e / / Se ar c h
7 12 5 22 13 32
target = 7
Linear Search Analysis: Worst Case
pr o c e dur e Se ar c h( my_a r r a y Ar r ay,
t ar g e t Num)
i Num
i <- 1 S c an the array
l oo p
e xi t i f ( ( i > MAX) OR ( my_a r r a y [ i ] = t a r ge t ) )
i <- i + 1
e ndl oop
7 12 5 22 13 32
target = 32
Searching Example
(Binary Search on Sorted List)
The Scenario
• We have a sorted array
7 12 42 59 71 86 104 212
A Better Search Algorithm
• Of course we could use our simpler search and
traverse the array
if no match then
look left (if need smaller) or
right (if need larger)
Look for 42
1 7 9 12 33 42 59 76 81 84 91 92 93 99
The Algorithm: Binary Search
look at “middle” element
if no match then
look left (if need smaller) or
right (if need larger)
1 7 9 12 33 42 59 76 81 84 91 92 93 99
Look for 42
The Algorithm: Binary Search
look at “middle” element
if no match then
look left (if need smaller) or
right (if need larger)
1 7 9 12 33 42 59 76 81 84 91 92 93 99
Look for 42
The Algorithm: Binary Search
look at “middle” element
if no match then
look left (if need smaller) or
right (if need larger)
1 7 9 12 33 42 59 76 81 84 91 92 93 99
Look for 42
The Algorithm: Binary Search
• Returns found or not found (true or false)
else
Look to the right
Looking Left
7 12 42 59 71 86 104 212
F L M L
Looking Right
7 12 42 59 71 86 104 212
F M F L
Binary Search Example – Found
7 12 42 59 71 86 104 212
F M L
Looking for 42
Binary Search Example – Found
7 12 42 59 71 86 104 212
F M L
Looking for 42
Binary Search Example – Found
7 12 42 59 71 86 104 212
F
M
L
42 found – in 3 comparisons
Binary Search Example – Not Found
7 12 42 59 71 86 104 212
F M L
Looking for 89
Binary Search Example – Not Found
7 12 42 59 71 86 104 212
F M L
Looking for 89
Binary Search Example – Not Found
7 12 42 59 71 86 104 212
F L
M
Looking for 89
Binary Search Example – Not Found
7 12 42 59 71 86 104 212
L F
1 7 9 12 33 42 59 76 81 84 91 92 93 99
Target: 59
Binary Search Analysis: Worst Case
Func t i o n Fi nd r e t ur n bo o l e a n ( A Ar r a y, f i r s t , l a s t , t o _ f i nd)
mi ddl e <- ( f i r s t + l as t ) di v 2
i f ( f i r s t > l a s t ) t he n
How many
r e t ur n f a l s e
e l s e i f ( A[ mi ddl e ] = t o _f i nd) t he n
comparisons??
r e t ur n t r ue
e l s e i f ( t o _ f i nd < A[ mi ddl e ] ) t he n
r e t ur n Fi nd( A, f i r s t , mi ddl e – 1 , t o _ f i nd)
el s e
r e t ur n Fi nd( A, mi ddl e +1 , l a s t , t o _f i nd)
e ndf unc t i o n
1 7 9 12 33 42 59 76 81 84 91 92 93 99
Binary Search Analysis: Worst Case
• With each comparison we throw away ½ of the list
N ………… 1 comparison
}
Selection Sort Example
Scan the items in the list to find the smallest element
65 35 25 85 50 55 70
25 35 65 85 50 55 70
25 35 65 85 50 55 70
25 35 65 85 50 55 70
25 35 50 85 65 55 70
25 35 50 55 65 85 70
25 35 50 55 65 85 70
25 35 50 55 65 70 85
Selection Sort Example
Selection Sort Example
Insertion Sort: Array-Based Lists
• Reduces number of key comparisons made in selection
sort
• Can be applied to both arrays and linked lists (examples
follow)
• The insertion sort algorithm sorts the list by moving each
element to its proper place
35 65 25 85 50 55 70
25 35 65 85 50 55 70
• Now, compare 85 with the previous elements:
25 35 65 85 50 55 70
25 35 65 85 50 55 70
25 35 50 65 85 55 70
• Now, compare 55 with the previous elements:
25 35 50 65 85 55 70
25 35 50 55 65 85 70
25 35 50 55 65 85 70
• A sorted list…
25 35 50 55 65 70 85
Quicksort Algorithm
Given an array of n elements (e.g., integers):
• If array only contains one element, return
• Else
– pick one element to use as pivot.
– Partition elements into two sub-arrays:
• Elements <= pivot
• Elements > pivot
– Quicksort (2 sub-arrays)
– Return results
Example
We are given array of n integers to sort:
40 20 10 80 60 50 7 30 100
Pick Pivot Element
There are a number of ways to pick the pivot element. In
this example, we will use the first element (as pivot) in
the array:
40 20 10 80 60 50 7 30 100
Partitioning Array
Given a pivot, partition the elements of the array
such that the resulting array consists of:
1. One sub-array that contains elements >= pivot
2. Another sub-array that contains elements < pivot
too_big_index too_small_index
1. While data[too_big_index] <= data[pivot]
++too_big_index
pivot_index = 0 40 20 10 80 60 50 7 30 100
too_big_index too_small_index
1. While data[too_big_index] <= data[pivot]
++too_big_index
pivot_index = 0 40 20 10 80 60 50 7 30 100
too_big_index too_small_index
1. While data[too_big_index] <= data[pivot]
++too_big_index
pivot_index = 0 40 20 10 80 60 50 7 30 100
too_big_index too_small_index
1. While data[too_big_index] <= data[pivot]
++too_big_index
2. While data[too_small_index] > data[pivot]
--too_small_index
pivot_index = 0 40 20 10 80 60 50 7 30 100
too_big_index too_small_index
1. While data[too_big_index] <= data[pivot]
++too_big_index
2. While data[too_small_index] > data[pivot]
--too_small_index
pivot_index = 0 40 20 10 80 60 50 7 30 100
too_big_index too_small_index
1. While data[too_big_index] <= data[pivot]
++too_big_index
2. While data[too_small_index] > data[pivot]
--too_small_index
3. If too_big_index < too_small_index
swap data[too_big_index] and data[too_small_index]
pivot_index = 0 40 20 10 80 60 50 7 30 100
too_big_index too_small_index
1. While data[too_big_index] <= data[pivot]
++too_big_index
2. While data[too_small_index] > data[pivot]
--too_small_index
3. If too_big_index < too_small_index
swap data[too_big_index] and data[too_small_index]
pivot_index = 0 40 20 10 30 60 50 7 80 100
too_big_index too_small_index
1. While data[too_big_index] <= data[pivot]
++too_big_index
2. While data[too_small_index] > data[pivot]
--too_small_index
3. If too_big_index < too_small_index
swap data[too_big_index] and data[too_small_index]
4. While too_small_index > too_big_index, go to step 1
pivot_index = 0 40 20 10 30 60 50 7 80 100
too_big_index too_small_index
1. While data[too_big_index] <= data[pivot]
++too_big_index
2. While data[too_small_index] > data[pivot]
--too_small_index
3. If too_big_index < too_small_index
swap data[too_big_index] and data[too_small_index]
4. While too_small_index > too_big_index, go to 1.
pivot_index = 0 40 20 10 30 60 50 7 80 100
too_big_index too_small_index
1. While data[too_big_index] <= data[pivot]
++too_big_index
2. While data[too_small_index] > data[pivot]
--too_small_index
3. If too_big_index < too_small_index
swap data[too_big_index] and data[too_small_index]
4. While too_small_index > too_big_index, go to 1.
pivot_index = 0 40 20
20 10
10 30
30 60 50
50 7 80 100
too_big_index too_small_index
1. While data[too_big_index] <= data[pivot]
++too_big_index
2. While data[too_small_index] > data[pivot]
--too_small_index
3. If too_big_index < too_small_index
swap data[too_big_index] and data[too_small_index]
4. While too_small_index > too_big_index, go to 1.
pivot_index = 0 40 20 10 30 60 50 7 80 100
too_big_index too_small_index
1. While data[too_big_index] <= data[pivot]
++too_big_index
2. While data[too_small_index] > data[pivot]
--too_small_index
3. If too_big_index < too_small_index
swap data[too_big_index] and data[too_small_index]
4. While too_small_index > too_big_index, go to 1.
pivot_index = 0 40 20 10 30 60 50 7 80 100
too_big_index too_small_index
1. While data[too_big_index] <= data[pivot]
++too_big_index
2. While data[too_small_index] > data[pivot]
--too_small_index
3. If too_big_index < too_small_index
swap data[too_big_index] and data[too_small_index]
4. While too_small_index > too_big_index, go to 1.
pivot_index = 0 40 20 10 30 60 50 7 80 100
too_big_index too_small_index
1. While data[too_big_index] <= data[pivot]
++too_big_index
2. While data[too_small_index] > data[pivot]
--too_small_index
3. If too_big_index < too_small_index
swap data[too_big_index] and data[too_small_index]
4. While too_small_index > too_big_index, go to 1.
pivot_index = 0 40 20 10 30 7 50 60 80 100
too_big_index too_small_index
1. While data[too_big_index] <= data[pivot]
++too_big_index
2. While data[too_small_index] > data[pivot]
--too_small_index
3. If too_big_index < too_small_index
swap data[too_big_index] and data[too_small_index]
4. While too_small_index > too_big_index, go to 1.
pivot_index = 0 40 20 10 30 7 50 60 80 100
too_big_index too_small_index
1. While data[too_big_index] <= data[pivot]
++too_big_index
2. While data[too_small_index] > data[pivot]
--too_small_index
3. If too_big_index < too_small_index
swap data[too_big_index] and data[too_small_index]
4. While too_small_index > too_big_index, go to 1.
pivot_index = 0 40 20 10 30 7 50 60 80 100
too_big_index too_small_index
1. While data[too_big_index] <= data[pivot]
++too_big_index
2. While data[too_small_index] > data[pivot]
--too_small_index
3. If too_big_index < too_small_index
swap data[too_big_index] and data[too_small_index]
4. While too_small_index > too_big_index, go to 1.
pivot_index = 0 40 20 10 30 7 50 60 80 100
too_big_index too_small_index
1. While data[too_big_index] <= data[pivot]
++too_big_index
2. While data[too_small_index] > data[pivot]
--too_small_index
3. If too_big_index < too_small_index
swap data[too_big_index] and data[too_small_index]
4. While too_small_index > too_big_index, go to 1.
pivot_index = 0 40 20 10 30 7 50 60 80 100
too_big_index too_small_index
1. While data[too_big_index] <= data[pivot]
++too_big_index
2. While data[too_small_index] > data[pivot]
--too_small_index
3. If too_big_index < too_small_index
swap data[too_big_index] and data[too_small_index]
4. While too_small_index > too_big_index, go to 1.
pivot_index = 0 40 20 10 30 7 50 60 80 100
too_big_index too_small_index
1. While data[too_big_index] <= data[pivot]
++too_big_index
2. While data[too_small_index] > data[pivot]
--too_small_index
3. If too_big_index < too_small_index
swap data[too_big_index] and data[too_small_index]
4. While too_small_index > too_big_index, go to 1.
pivot_index = 0 40 20 10 30 7 50 60 80 100
too_big_index too_small_index
1. While data[too_big_index] <= data[pivot]
++too_big_index
2. While data[too_small_index] > data[pivot]
--too_small_index
3. If too_big_index < too_small_index
swap data[too_big_index] and data[too_small_index]
4. While too_small_index > too_big_index, go to 1.
pivot_index = 0 40 20 10 30 7 50 60 80 100
too_big_index too_small_index
1. While data[too_big_index] <= data[pivot]
++too_big_index
2. While data[too_small_index] > data[pivot]
--too_small_index
3. If too_big_index < too_small_index
swap data[too_big_index] and data[too_small_index]
4. While too_small_index > too_big_index, go to 1.
pivot_index = 0 40 20 10
10 30
30 7 50 60 80 100
too_big_index too_small_index
1. While data[too_big_index] <= data[pivot]
++too_big_index
2. While data[too_small_index] > data[pivot]
--too_small_index
3. If too_big_index < too_small_index
swap data[too_big_index] and data[too_small_index]
4. While too_small_index > too_big_index, go to 1.
5. Swap data[too_small_index] and data[pivot_index]
pivot_index = 0 40 20 10 30 7 50 60 80 100
[0] [1] [2] [3] [4] [5] [6] [7] [8]
too_big_index too_small_index
1. While data[too_big_index] <= data[pivot]
++too_big_index
2. While data[too_small_index] > data[pivot]
--too_small_index
3. If too_big_index < too_small_index
swap data[too_big_index] and data[too_small_index]
4. While too_small_index > too_big_index, go to 1.
5. Swap data[too_small_index] and data[pivot_index]
pivot_index = 4 7 20 10 30 40 50 60 80 100
too_big_index too_small_index
Partition Result
7 20 10 30 40 50 60 80 100
7 20 10 30 40 50 60 80 100
99 6 86 15 58 35 86 4 0
Merge Sort Example
99 6 86 15 58 35 86 4 0
99 6 86 15 58 35 86 4 0
Merge Sort Example
99 6 86 15 58 35 86 4 0
99 6 86 15 58 35 86 4 0
99 6 86 15 58 35 86 4 0
Merge Sort Example
99 6 86 15 58 35 86 4 0
99 6 86 15 58 35 86 4 0
99 6 86 15 58 35 86 4 0
99 6 86 15 58 35 86 4 0
Merge Sort Example
99 6 86 15 58 35 86 4 0
99 6 86 15 58 35 86 4 0
99 6 86 15 58 35 86 4 0
99 6 86 15 58 35 86 4 0
4 0
Merge Sort Example
99 6 86 15 58 35 86 0 4
Merge 4 0
Merge Sort Example
6 99 15 86 35 58 0 4 86
99 6 86 15 58 35 86 0 4
Merge
Merge Sort Example
6 15 86 99 0 4 35 58 86
6 99 15 86 35 58 0 4 86
Merge
Merge Sort Example
0 4 6 15 35 58 86 86 99
6 15 86 99 0 4 35 58 86
Merge
Merge Sort: Sorted Values
0 4 6 15 35 58 86 86 99
Merge Sort (Array, Left-index, right-index)
Merge
• Easy concept, tricky code
• lots of special cases:
• keep track of two indices to step through both
arrays (the “front” of each array)
• Indices do not necessarily move at the same
speed
• Stop loop when either index reaches the end
• Two arrays are not necessarily the same size
• What to do when you reach the end of one
array but not the other?
• copy from temp back into the array
Merge
Time Complexity Analysis
• Worst case: O(nlog2n)
• Average case: O(nlog2n)
• Best case: O(nlog2n)
Comparison of Sorting Algorithms