Are there any resources on how the mergeSort used by Arrays.sort(Object[] a) is implemented? While it is documented quite good, I have a hard time understanding it (especially why the src and dest are are switched when mergeSort() get's recursively called).
+8
A:
Here is the source of java.util.Arrays
.
Actually, you have that source code in the JDK - just open java.util.Arrays
in your IDE and the source code + the comments will appear. If you don't have an IDE, look at JDK_HOME\src.zip
Then, put it in your IDE and trace how it works.
- put breakpoints (and run a program in debug mode)
- use
System.out.println(..)
- change parts of it to see how they are reflected.
- read the wikipedia article about merge sort
- pay attention to this comment:
// Recursively sort halves of dest into src
Bozho
2010-02-07 20:02:55
It **appears** the OP already saw the source (since s/he mentions the fact that the `src` and `dest` arrays are switched when recursively called) but has a hard time understanding the logic.
Bart Kiers
2010-02-07 20:13:03
hm, yes. I gave some pointers on how to understand it better.
Bozho
2010-02-07 20:15:20
I could be wrong of course... Anyway, I was going to suggest the OP to use the *poor-man's debugger* (putting some System.out.println's in the algorithm), but you beat me to it!
Bart Kiers
2010-02-07 20:18:19
:) it was in the original answer, but wasn't that much pointed out.
Bozho
2010-02-07 20:19:32
Thanks, didn't know the sources were available in src.zip. I only read the class file which Eclipse opened but which I wasn't able to debug (which makes sense ^^). But with the source, I was able to modify the code, put in some breakpoints and finally realized how it works.
Helper Method
2010-02-08 15:24:43
+1
A:
This article could help you to understand mergesort better before you go into the (optimzed) libary code.
stacker
2010-02-07 20:18:55
The library code is actually not really optimized, it's a misconception. I've had a serious issue with it on a 16-cores Mac / 20 GB of ram and huge datasets: it is mono-threaded. So 15 of my cores were idling. I had to rewrite a multi-threaded sort algo myself (I rewrote quicksort out of lazyness, for it's slightly easier than mergesort). So it's "optimized" when put back in the concept of the 90's and early 200x, where single-core CPUs where the norm :)
Webinator
2010-02-07 20:39:30
A:
I understand how the algorithm works, but what I don't understand why the recursion in the end always returns the dest array (switching dest and src on any recursive call). Here's the implementation:
private static void mergeSort(Object[] src,
Object[] dest,
int low,
int high,
int off) {
int length = high - low;
// Insertion sort on smallest arrays
if (length < INSERTIONSORT_THRESHOLD) {
for (int i=low; i<high; i++)
for (int j=i; j>low &&
((Comparable) dest[j-1]).compareTo(dest[j])>0; j--)
swap(dest, j, j-1);
return;
}
// Recursively sort halves of dest into src
int destLow = low;
int destHigh = high;
low += off;
high += off;
int mid = (low + high) >>> 1;
mergeSort(dest, src, low, mid, -off);
mergeSort(dest, src, mid, high, -off);
// If list is already sorted, just copy from src to dest. This is an
// optimization that results in faster sorts for nearly ordered lists.
if (((Comparable)src[mid-1]).compareTo(src[mid]) <= 0) {
System.arraycopy(src, low, dest, destLow, length);
return;
}
// Merge sorted halves (now in src) into dest
for(int i = destLow, p = low, q = mid; i < destHigh; i++) {
if (q >= high || p < mid && ((Comparable)src[p]).compareTo(src[q])<=0)
dest[i] = src[p++];
else
dest[i] = src[q++];
}
}
Helper Method
2010-02-09 21:22:37