2. Merging two sorted arrays To merge two sorted arrays into a
third (sorted) array, repeatedly compare the two least elements and
copy the smaller of the two 7 9 14 18 5 10 12 20 5 7 9 10 12 14 18
20
3. Merging parts of a single array The procedure really is no
different if the two arrays are really portions of a single array
first part second part 7 9 14 18 5 10 12 20 5 7 9 10 12 14 18
20
4. Sorting an array If we start with an array in which the left
half is sorted and the right half is sorted, we can merge them into
a single sorted array We need to copy our temporary array back up 7
9 14 18 5 10 12 20 7 9 14 18 5 10 12 20 This is a sorting technique
called mergesort
5. Recursion How did the left and right halves of our array get
sorted? Obviously, by mergesorting them To mergesort an array:
Mergesort the left half Mergesort the right half Merge the two
sorted halves Each recursive call is with a smaller portion of the
array The base case: Mergesort an array of size 1
6. The actual codeprivate void recMergeSort(long[] workspace,
int lowerBound, int upperBound) { if (lowerBound == upperBound)
return; int mid = (lowerBound + upperBound) / 2;
recMergeSort(workspace, lowerBound, mid); recMergeSort(workspace,
mid + 1, upperBound); merge(workspace, lowerBound, mid + 1,
upperBound);} from Lafore, p. 287
7. The merge method The merge method is too ugly to show It
requires: The index of the first element in the left subarray The
index of the last element in the right subarray The index of the
first element in the right subarray That is, the dividing line
between the two subarrays The index of the next value in the left
subarray The index of the next value in the right subarray The
index of the destination in the workspace But conceptually, it isnt
difficult!
8. Analysis of the merge operation The basic operation is:
compare two elements, move one of them to the workspace array This
takes constant time We do this comparison n times Hence, the whole
thing takes O(n) time Now we move the n elements back to the
original array Each move takes constant time Hence moving all n
elements takes O(n) time Total time: O(n) + O(n) = O(n)
9. But wait...theres more So far, weve found that it takes O(n)
time to merge two sorted halves of an array How did these subarrays
get sorted? At the next level down, we had four subarrays, and we
merged them pairwise Since merging arrays is linear time, when we
cut the array size in half, we cut the time in half But there are
two arrays of size n/2 Hence, all merges combined at the next lower
level take the same amount of time as a single merge at the upper
level
10. Analysis II So far we have seen that it takes O(n) time to
merge two subarrays of size n/2 O(n) time to merge four subarrays
of size n/4 into two subarrays of size n/2 O(n) time to merge eight
subarrays of size n/8 into four subarrays of size n/4 Etc. How many
levels deep do we have to proceed? How many times can we divide an
array of size n into two halves? log2n, of course
11. Analysis III So if our recursion goes log n levels deep...
...and we do O(n) work at each level... ...our total time is: log n
* O(n)... ...or in other words, O(n log n) For large arrays, this
is much better than Bubblesort, Selection sort, or Insertion sort,
all of which are O(n2) Mergesort does, however, require a workspace
array as large as our original array
12. Stable sort algorithms A stable sort keeps equal elements
in Ann 98 Ann 98 the same order Bob 90 Joe 98 This may matter Dan
75 Bob 90 when you are sorting data Joe 98 Sam 90 according to some
Pat 86 Pat 86 characteristic Sam 90 Ze 86 Example: sorting Ze 86
Dan 75 students by test scores original stably array sorted
13. Unstable sort algorithms An unstable sort Ann 98 Joe 98 may
or may not keep equal Bob 90 Ann 98 elements in the Dan 75 Bob 90
same order Joe 98 Sam 90 Stability is usually Pat 86 Ze 86 not
important, but Sam 90 Pat 86 sometimes it matters Ze 86 Dan 75
original unstably array sorted
14. Is mergesort stable?private void recMergeSort(long[]
workspace, int lowerBound, int upperBound) { if (lowerBound ==
upperBound) return; int mid = (lowerBound + upperBound) / 2;
recMergeSort(workspace, lowerBound, mid); recMergeSort(workspace,
mid + 1, upperBound); merge(workspace, lowerBound, mid + 1,
upperBound);} Is this sort stable? recMergeSort does none of the
actual work of moving elements aroundthats done in merge
15. Stability of merging Stability of mergesort depends on the
merge method After all, this is the only place where elements get
moved 7 9 14 18 5 10 12 20 5 7 9 10 12 14 18 20 What if we
encounter equal elements when merging? If we always choose the
element from the left subarray, mergesort is stable