merge sort: illustrated step-by-step walk through
DESCRIPTION
A step-by-step illustration of Merge sort to help you walk through a series of operations. Illustration is accompanied by actual code with bold line indicating the current operation.TRANSCRIPT
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