0% found this document useful (0 votes)
60 views

05 Recursion Part 2 (Merge Sort)

The document describes the recursive implementation of merge sort. It divides the array recursively into smaller sub-arrays of size 1, sorts those sub-arrays using a base case of returning a single element array, and then merges the sorted sub-arrays together using a merge function to produce the final sorted array. The recursive calls sort the sub-problems, while the merging combines the solutions to produce the final sorted list.

Uploaded by

Isabelle Seet
Copyright
© © All Rights Reserved
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
60 views

05 Recursion Part 2 (Merge Sort)

The document describes the recursive implementation of merge sort. It divides the array recursively into smaller sub-arrays of size 1, sorts those sub-arrays using a base case of returning a single element array, and then merges the sorted sub-arrays together using a merge function to produce the final sorted array. The recursive calls sort the sub-problems, while the merging combines the solutions to produce the final sorted list.

Uploaded by

Isabelle Seet
Copyright
© © All Rights Reserved
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 19

Merge Sort

✦ Last week we have seen the iterative version of merge sort


✦ The iterative definition is based on bottom-up strategy
❖ Begin with individual elements
❖ Iteratively merge groups of increasing sizes
✦ Merge sort can also be described recursively
✦ The recursive definition is based on top-down strategy
❖ Begin with the full array to be sorted
❖ Divide the array into shorter arrays to be sorted
❖ Sort the shorter arrays recursively
Merge Sort: Divide
0 1 2 3 4 5 6 7
41 31 93 15 40 32 9 70
split into two lists and
msort each shorter list
0 1 2 3 4 5 6 7

41 31 93 15 40 32 9 70
Divide

0 1 2 3 4 5 6 7

41 31 93 15 40 32 9 70

0 1 2 3 4 5 6 7

41 31 93 15 40 32 9 70
Merge Sort: Conquer
0 1 2 3 4 5 6 7
41 31 93 15 40 32 9 70

0 1 2 3 4 5 6 7

41 31 93 15 40 32 9 70
Conquer

0 1 2 3 4 5 6 7

41 31 93 15 40 32 9 70

0 1 2 3 4 5 6 7

41 31 93 15 40 32 9 70
base case only 1 item,
consider it already sorted
Merge Sort: Conquer
0 1 2 3 4 5 6 7
41 31 93 15 40 32 9 70

0 1 2 3 4 5 6 7

41 31 93 15 40 32 9 70
Conquer

0 1 2 3 4 5 6 7

31 41 15 93 32 40 9 70
merge sorted
lists
0 1 2 3 4 5 6 7

41 31 93 15 40 32 9 70
Merge Sort: Conquer
0 1 2 3 4 5 6 7
41 31 93 15 40 32 9 70

0 1 2 3 4 5 6 7

15 31 41 93 9 32 40 70
Conquer
merge sorted
lists
0 1 2 3 4 5 6 7

31 41 15 93 32 40 9 70

0 1 2 3 4 5 6 7

41 31 93 15 40 32 9 70
Merge Sort: Conquer
0 1 2 3 4 5 6 7
9 15 31 32 40 41 70 93
merge sorted
lists
0 1 2 3 4 5 6 7

15 31 41 93 9 32 40 70
Conquer

0 1 2 3 4 5 6 7

31 41 15 93 32 40 9 70

0 1 2 3 4 5 6 7

41 31 93 15 40 32 9 70
Recursive Version of Merge Sort
01 def rmSort(a):
02 if len(a) == 1:
03 return a
04 mid = len(a)//2
05 a1 = rmSort(a[0:mid])
06 a2 = rmSort(a[mid:len(a)])
07 return merge2(a1, a2)
Recursive Version of Merge Sort
01 def rmSort(a):
02 if len(a) == 1: base case – single element

03 return a
04 mid = len(a)//2
05 a1 = rmSort(a[0:mid]) recursive call to smaller instances of the
original problem
06 a2 = rmSort(a[mid:len(a)])
07 return merge2(a1, a2)
merge results from two sub-problems
Recursive Version of Merge Sort
# takes in 2 sorted lists (a1 and a2)
# returns a1 + a2 sorted
def merge2(a1, a2): Repeat as long as
i = 0 there is at least 1 element in a1 OR
j = 0 there is at least 1 element in a2
r = []
while i < len(a1) or j < len(a2):
if (j == len(a2)) or (i < len(a1) and a1[i] < a2[j]):
r.append(a1[i]) # pick item from a1
i += 1
else:
r.append(a2[j]) # pick item from a2
j += 1
return r

There is at least 1 element in a1 AND the


current element in a1 is smaller than the
current element in a2
No more elements in a2
Sequence of Calls to rmsort
0 1 2 3 4 5 6 7
41 31 93 15 40 32 9 70
1st 8th

0 1 2 3 4 5 6 7

41 31 93 15 40 32 9 70
Divide
2nd 5th 9th 12th

0 1 2 3 4 5 6 7

41 31 93 15 40 32 9 70
3rd 4th 6th 7th 10th 11th 13th 14th
0 1 2 3 4 5 6 7

41 31 93 15 40 32 9 70
Sequence of Calls to merge2
0 1 2 3 4 5 6 7
9 15 31 32 40 41 70 93
7th
0 1 2 3 4 5 6 7

15 31 41 93 9 32 40 70
Conquer
3rd 6th
0 1 2 3 4 5 6 7

31 41 15 93 32 40 9 70
1st 2nd 4th 5th
0 1 2 3 4 5 6 7

41 31 93 15 40 32 9 70
Complexity of Recursive Merge Sort

✦ Number of comparisons is the same for both iterative and recursive versions
✦ In the recursive version:
❖ There are log n levels of recursion with decreasing group size size (in the above case, it’s 8, 4,
and 2).
❖ For each level, there are (2 x n / size) recursive function calls.
❖ Each recursive function call has a merge2 operation, which conducts up to size comparisons in
the worst case.
✦ Complexity of recursive merge sort is O(n log n).
In-Class Exercise Q3
For the following input arrays, determine the state of
the array just before the final merge step for the two
versions of merge sort:
• bottom-up non-recursive version
• top-down recursive version

(a) [26, 34, 64, 83, 2, 5]

(b) [52, 30, 98, 59, 67, 4, 64, 12, 79]


Another Example: Binary Search

# iterative version of bsearch


def bsearch(array, target):
lower = -1
upper = len(array)

while not (lower + 1 == upper):


mid = (lower + upper)//2
if target == array[mid]: #success
return mid
elif target < array[mid]:
upper = mid #search lower region
else:
lower = mid #search upper region
return -1 #not found
…Another Example: Binary Search

# recursive version of bsearch


01 def rbsearch(array, target, lower=None, upper=None):
02 if lower == None: only happens when
03 lower = -1 rbsearch is called the 1st
04 upper = len(array) time
05
06 if lower + 1 == upper: # base case
07 return -1 # not found
08 mid = (lower + upper)//2
09 if array[mid] == target: # success
10 return mid
11 elif array[mid] < target: # search upper region
12 return rbsearch(array, target, mid, upper)
13 else: # search lower region
14 return rbsearch(array, target, lower, mid)
Summary

✦ An algorithm that uses divide and conquer can be written using iteration or recursion
❖ recursive = “self-similar”
❖ a problem that can be divided into smaller subproblems
❖ a recursive function calls itself
✦ Fundamentals of recursion:
❖ reduction step
❖ base case
✦ Recursive versions of:
❖ merge sort
Further reading materials

✦ Online sources:
❖ http://www.cs.uiuc.edu/~jeffe/teaching/algorithms/notes/01-recursion.pdf
❖ http://www-cs-faculty.stanford.edu/~eroberts/courses/cs106b/chapters/05-intro-to-recursion.pdf
❖ http://introcs.cs.princeton.edu/java/23recursion/

✦ Optional supplementary text (available in Library):


❖ Prichard and Carrano, Data Abstraction and Problem Solving with Java
‣ Chapter 3 “Recursion: The Mirrors”
Optional Reading:
What is “Tail Recursion”?

✦ https://stackoverflow.com/questions/33923/what-is-tail-recursion
Road Map

Algorithm Design and Analysis


(Weeks 1 - 5)

Fundamental Data Structures


Next week ✦ Week 6: Linear data structures (stack, queue)
✦ Week 7: Hierarchical data structure (binary tree)
✦ Week 9: Networked data structure (graph)
✦ Week 10: Graph Algorithms

Computational Intractability and Heuristic Reasoning


(Weeks 11 - 13)

You might also like