Post on 24-May-2015
description
Merge Sort algorithmIllustrated walkthrough
Reference
“Cracking the coding interview” Fifth edition. Gayle Laakmann McDowell, 2008 - 2013
Merge function
This function does the most of the heavy lifting, so we look at it first, then see it in the context of Merge Sort algorithm
for (int i = begin; i <= last; i++) { helper[i] = array[i];}
int left = begin;int right = middle + 1;int storeIndex = begin;
while (left <= middle && right <= last) { if (helper[left] <= helper[right]) { array[storeIndex] = helper[left]; left++; } else { array[storeIndex] = helper[right]; right++; }
storeIndex++;}
int remainder = middle - left;for (int i = 0; i <= remainder; i++) { array[storeIndex + i] = helper[left + i];}
Part #1: prepare helper
Part #2: pick smaller and copy to the target
Part #3: copy any remainder from left(right not necessary)
Merge Function
10 30 20 40
[0] [1] [2] [3]
array
begin middle last
left sub-arrayalready sorted within the sub-array
right sub-arrayalready sorted within the sub-array
left sub-array{begin..middle}
right sub-array{middle+1..last}
10 30 20 40
[0]
for (int i = begin; i <= last; i++) { helper[i] = array[i];}
[1] [2] [3]
helper
array
10 30 20 40
[0]
for (int i = begin; i <= last; i++) { helper[i] = array[i];}
[1] [2] [3]
helper 10 30 20 40
array
int left = begin;int right = middle + 1;int storeIndex = begin;
10 30 20 40
[0] [1] [2] [3]
helper 10 30 20 40
array
left
begin middle last
int left = begin;int right = middle + 1;int storeIndex = begin;
10 30 20 40
[0] [1] [2] [3]
helper 10 30 20 40
right
array
left
int left = begin;int right = middle + 1;int storeIndex = begin;
10 30 20 40
[0] [1] [2] [3]
helper
store Index
10 30 20 40
right
array
left
while (left <= middle && right <= last) { if (helper[left] <= helper[right]) { array[storeIndex] = helper[left]; left++; } else { array[storeIndex] = helper[right]; right++; }
storeIndex++;}
10 30 20 40
[0] [1] [2] [3]
helper
store Index
10 30 20 40
right
array
left
0 <= 1is true
2 <= 3is true
while (left <= middle && right <= last) { if (helper[left] <= helper[right]) { array[storeIndex] = helper[left]; left++; } else { array[storeIndex] = helper[right]; right++; }
storeIndex++;}
10 30 20 40
[0] [1] [2] [3]
helper
store Index
10 30 20 40
right
array
left
10 <= 20is true
while (left <= middle && right <= last) { if (helper[left] <= helper[right]) { array[storeIndex] = helper[left]; left++; } else { array[storeIndex] = helper[right]; right++; }
storeIndex++;}
10 30 20 40
[0] [1] [2] [3]
helper
store Index
10 30 20 40
right
array
left
while (left <= middle && right <= last) { if (helper[left] <= helper[right]) { array[storeIndex] = helper[left]; left++; } else { array[storeIndex] = helper[right]; right++; }
storeIndex++;}
10 30 20 40
[0] [1] [2] [3]
helper
store Index
10 30 20 40
right
array
left
while (left <= middle && right <= last) { if (helper[left] <= helper[right]) { array[storeIndex] = helper[left]; left++; } else { array[storeIndex] = helper[right]; right++; }
storeIndex++;}
10 30 20 40
[0] [1] [2] [3]
helper
store Index
10 30 20 40
right
array
left
while (left <= middle && right <= last) { if (helper[left] <= helper[right]) { array[storeIndex] = helper[left]; left++; } else { array[storeIndex] = helper[right]; right++; }
storeIndex++;}
10 30 20 40
[0] [1] [2] [3]
helper 10 30 20 40
right
array
left
1 <= 1is true
2 <= 3is truestore
Index
while (left <= middle && right <= last) { if (helper[left] <= helper[right]) { array[storeIndex] = helper[left]; left++; } else { array[storeIndex] = helper[right]; right++; }
storeIndex++;}
10 30 20 40
[0] [1] [2] [3]
helper 10 30 20 40
right
array
left
store Index
30 <= 20is false
while (left <= middle && right <= last) { if (helper[left] <= helper[right]) { array[storeIndex] = helper[left]; left++; } else { array[storeIndex] = helper[right]; right++; }
storeIndex++;}
10 20 20 40
[0] [1] [2] [3]
helper 10 30 20 40
right
array
left
store Index
while (left <= middle && right <= last) { if (helper[left] <= helper[right]) { array[storeIndex] = helper[left]; left++; } else { array[storeIndex] = helper[right]; right++; }
storeIndex++;}
10 20 20 40
[0] [1] [2] [3]
helper 10 30 20 40
right
array
left
store Index
while (left <= middle && right <= last) { if (helper[left] <= helper[right]) { array[storeIndex] = helper[left]; left++; } else { array[storeIndex] = helper[right]; right++; }
storeIndex++;}
10 20 20 40
[0] [1] [2] [3]
helper 10 30 20 40
right
array
left
store Index
while (left <= middle && right <= last) { if (helper[left] <= helper[right]) { array[storeIndex] = helper[left]; left++; } else { array[storeIndex] = helper[right]; right++; }
storeIndex++;}
10 20 20 40
[0] [1] [2] [3]
helper 10 30 20 40
right
array
left
store Index
1 <= 1is true
3 <= 3is true
while (left <= middle && right <= last) { if (helper[left] <= helper[right]) { array[storeIndex] = helper[left]; left++; } else { array[storeIndex] = helper[right]; right++; }
storeIndex++;}
10 20 20 40
[0] [1] [2] [3]
helper 10 30 20 40
right
array
left
store Index
30 <= 40is true
while (left <= middle && right <= last) { if (helper[left] <= helper[right]) { array[storeIndex] = helper[left]; left++; } else { array[storeIndex] = helper[right]; right++; }
storeIndex++;}
10 20 30 40
[0] [1] [2] [3]
helper 10 30 20 40
right
array
left
store Index
while (left <= middle && right <= last) { if (helper[left] <= helper[right]) { array[storeIndex] = helper[left]; left++; } else { array[storeIndex] = helper[right]; right++; }
storeIndex++;}
10 20 30 40
[0] [1] [2] [3]
helper 10 30 20 40
right
array
left
store Index
while (left <= middle && right <= last) { if (helper[left] <= helper[right]) { array[storeIndex] = helper[left]; left++; } else { array[storeIndex] = helper[right]; right++; }
storeIndex++;}
10 20 30 40
[0] [1] [2] [3]
helper 10 30 20 40
right
array
left
store Index
while (left <= middle && right <= last) { if (helper[left] <= helper[right]) { array[storeIndex] = helper[left]; left++; } else { array[storeIndex] = helper[right]; right++; }
storeIndex++;}
10 20 30 40
[0] [1] [2] [3]
helper 10 30 20 40
right
array
left
store Index
2 <= 1is false
3 <= 3is true
Exit while loop
int remainder = middle - left;for (int i = 0; i <= remainder; i++) { array[storeIndex + i] = helper[left + i];}
10 20 30 40
[0] [1] [2] [3]
helper 10 30 20 40
right
array
left
store Index
-1
remainder
1 - 2 = -1
int remainder = middle - left;for (int i = 0; i <= remainder; i++) { array[storeIndex + i] = helper[left + i];}
10 20 30 40
[0] [1] [2] [3]
helper 10 30 20 40
right
array
left
store Index
-1
remainder
0 <= -1is false
Skip over for loop
int remainder = middle - right;for (int i = 0; i <= remainder ; i++) { array[storeIndex + i] = helper[ right + i];}
10 20 30 40
[0] [1] [2] [3]
helper 10 30 20 40
right
array
left
store Index
Not needed
Already there because right sub-array already occupies tail end of the target array
Merge Sort Algorithm
Now we use Merge function
if (begin >= last) { return;}
int middle = (begin + last) / 2; MergeSort(array, helper, begin, middle);MergeSort(array, helper, middle + 1, last); Merge(array, helper, begin, middle, last);
begin last
5 7 3 2
[0] [1] [2] [3]
if (begin >= last) { return;}
int middle = (begin + last) / 2; MergeSort(array, helper, begin, middle);MergeSort(array, helper, middle + 1, last); Merge(array, helper, begin, middle, last);
0 >= 3is false
begin last
5 7 3 2
[0] [1] [2] [3]
if (begin >= last) { return;}
int middle = (begin + last) / 2; MergeSort(array, helper, begin, middle);MergeSort(array, helper, middle + 1, last); Merge(array, helper, begin, middle, last);
begin last
5 7 3 2
[0] [1] [2] [3]
middle
if (begin >= last) { return;}
int middle = (begin + last) / 2; MergeSort(array, helper, begin, middle);MergeSort(array, helper, middle + 1, last); Merge(array, helper, begin, middle, last);
begin last
5 7 3 2
[0] [1] [2] [3]
middle
Call Stack #0
Merge & Sort the left sub-array first
if (begin >= last) { return;}
int middle = (begin + last) / 2; MergeSort(array, helper, begin, middle);MergeSort(array, helper, middle + 1, last); Merge(array, helper, begin, middle, last);
begin last
5 7 3 2
[0] [1] [2] [3]
Call Stack #0
Call Stack #1
if (begin >= last) { return;}
int middle = (begin + last) / 2; MergeSort(array, helper, begin, middle);MergeSort(array, helper, middle + 1, last); Merge(array, helper, begin, middle, last);
begin last
5 7 3 2
[0] [1] [2] [3]
Call Stack #0
Call Stack #1
0 >= 1is false
if (begin >= last) { return;}
int middle = (begin + last) / 2; MergeSort(array, helper, begin, middle);MergeSort(array, helper, middle + 1, last); Merge(array, helper, begin, middle, last);
begin last
5 7 3 2
[0] [1] [2] [3]
Call Stack #0
Call Stack #1
middle
if (begin >= last) { return;}
int middle = (begin + last) / 2; MergeSort(array, helper, begin, middle);MergeSort(array, helper, middle + 1, last); Merge(array, helper, begin, middle, last);
begin last
5 7 3 2
[0] [1] [2] [3]
Call Stack #0
Call Stack #1
middle
if (begin >= last) { return;}
int middle = (begin + last) / 2; MergeSort(array, helper, begin, middle);MergeSort(array, helper, middle + 1, last); Merge(array, helper, begin, middle, last);
beginlast
5 7 3 2
[0] [1] [2] [3]
Call Stack #0
Call Stack #1
Call Stack #3
if (begin >= last) { return;}
int middle = (begin + last) / 2; MergeSort(array, helper, begin, middle);MergeSort(array, helper, middle + 1, last); Merge(array, helper, begin, middle, last);
beginlast
5 7 3 2
[0] [1] [2] [3]
Call Stack #0
Call Stack #1
Call Stack #30 >=0is true
if (begin >= last) { return;}
int middle = (begin + last) / 2; MergeSort(array, helper, begin, middle);MergeSort(array, helper, middle + 1, last); Merge(array, helper, begin, middle, last);
beginlast
5 7 3 2
[0] [1] [2] [3]
Call Stack #0
Call Stack #1
Call Stack #30 >=0is true
Base condition is met!
if (begin >= last) { return;}
int middle = (begin + last) / 2; MergeSort(array, helper, begin, middle);MergeSort(array, helper, middle + 1, last); Merge(array, helper, begin, middle, last);
3 2
[2] [3]
Call Stack #0
Call Stack #1
begin last
5 7
[0] [1]
middle
if (begin >= last) { return;}
int middle = (begin + last) / 2; MergeSort(array, helper, begin, middle);MergeSort(array, helper, middle + 1, last); Merge(array, helper, begin, middle, last);
3 2
[2] [3]
Call Stack #0
Call Stack #1
5 7
[0] [1]
beginlast
Call Stack #31 >=1is true
if (begin >= last) { return;}
int middle = (begin + last) / 2; MergeSort(array, helper, begin, middle);MergeSort(array, helper, middle + 1, last); Merge(array, helper, begin, middle, last);
3 2
[2] [3]
Call Stack #0
Call Stack #1
5 7
[0] [1]
beginlast
Call Stack #3
Base condition is met!
if (begin >= last) { return;}
int middle = (begin + last) / 2; MergeSort(array, helper, begin, middle);MergeSort(array, helper, middle + 1, last); Merge(array, helper, begin, middle, last);
begin last
5 7 3 2
[0] [1] [2] [3]
Call Stack #0
Call Stack #1
middle
Merge
if (begin >= last) { return;}
int middle = (begin + last) / 2; MergeSort(array, helper, begin, middle);MergeSort(array, helper, middle + 1, last); Merge(array, helper, begin, middle, last);(implicit return at the end of function)
begin last
5 7 3 2
[0] [1] [2] [3]
Call Stack #0
Call Stack #1
middle
Already sorted (unchanged but sorted)
if (begin >= last) { return;}
int middle = (begin + last) / 2; MergeSort(array, helper, begin, middle);MergeSort(array, helper, middle + 1, last); Merge(array, helper, begin, middle, last);
begin last
5 7 3 2
[0] [1] [2] [3]
middle
Call Stack #0
Merge & Sort the right sub-array next
if (begin >= last) { return;}
int middle = (begin + last) / 2; MergeSort(array, helper, begin, middle);MergeSort(array, helper, middle + 1, last); Merge(array, helper, begin, middle, last);
begin last
5 7 3 2
[0] [1] [2] [3]
Call Stack #0
Walkthrough ends here.The right sub-array is processed the same way as the left sub-array.After that, Merge is called with two already-sorted sub-arrays
Call Stack #1