Merge sort: illustrated step-by-step walk through

Post on 24-May-2015

1.597 views 3 download

Tags:

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 of Merge sort: illustrated step-by-step walk through

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