|
|
@ -29,7 +29,6 @@ |
|
|
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
|
|
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
|
|
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
|
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
|
|
package com.jme3.util; |
|
|
|
package com.jme3.util; |
|
|
|
|
|
|
|
|
|
|
|
import java.util.Arrays; |
|
|
|
import java.util.Arrays; |
|
|
@ -39,58 +38,133 @@ import java.util.Comparator; |
|
|
|
* Quick and merge sort implementations that create no garbage, unlike {@link |
|
|
|
* Quick and merge sort implementations that create no garbage, unlike {@link |
|
|
|
* Arrays#sort}. The merge sort is stable, the quick sort is not. |
|
|
|
* Arrays#sort}. The merge sort is stable, the quick sort is not. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public class SortUtil |
|
|
|
public class SortUtil { |
|
|
|
{ |
|
|
|
|
|
|
|
public static void gsort(Object[] a, Comparator comp){ |
|
|
|
/** |
|
|
|
int p = 0; |
|
|
|
* The size at or below which we will use insertion sort because it's |
|
|
|
int l = a.length; |
|
|
|
* probably faster. |
|
|
|
while (p < l){ |
|
|
|
*/ |
|
|
|
int pm1 = p-1; |
|
|
|
private static final int INSERTION_SORT_THRESHOLD = 7; |
|
|
|
if (p == 0 || comp.compare(a[p], a[pm1]) >= 0){ |
|
|
|
|
|
|
|
p++; |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
procedure optimizedGnomeSort(a[]) |
|
|
|
|
|
|
|
pos := 1 |
|
|
|
|
|
|
|
last := 0 |
|
|
|
|
|
|
|
while pos < length(a) |
|
|
|
|
|
|
|
if (a[pos] >= a[pos-1]) |
|
|
|
|
|
|
|
if (last != 0) |
|
|
|
|
|
|
|
pos := last |
|
|
|
|
|
|
|
last := 0 |
|
|
|
|
|
|
|
end if |
|
|
|
|
|
|
|
pos := pos + 1 |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
swap a[pos] and a[pos-1] |
|
|
|
|
|
|
|
if (pos > 1) |
|
|
|
|
|
|
|
if (last == 0) |
|
|
|
|
|
|
|
last := pos |
|
|
|
|
|
|
|
end if |
|
|
|
|
|
|
|
pos := pos - 1 |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
pos := pos + 1 |
|
|
|
|
|
|
|
end if |
|
|
|
|
|
|
|
end if |
|
|
|
|
|
|
|
end while |
|
|
|
|
|
|
|
end procedure |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public static void gsort(Object[] a, Comparator comp) { |
|
|
|
|
|
|
|
int pos = 1; |
|
|
|
|
|
|
|
int last = 0; |
|
|
|
|
|
|
|
int length = a.length; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
while (pos < length){ |
|
|
|
|
|
|
|
if ( comp.compare(a[pos], a[pos-1]) >= 0 ){ |
|
|
|
|
|
|
|
if (last != 0){ |
|
|
|
|
|
|
|
pos = last; |
|
|
|
|
|
|
|
last = 0; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
pos ++; |
|
|
|
}else{ |
|
|
|
}else{ |
|
|
|
Object t = a[p]; |
|
|
|
Object tmp = a[pos]; |
|
|
|
a[p] = a[pm1]; |
|
|
|
a[pos] = a[pos-1]; |
|
|
|
a[pm1] = t; |
|
|
|
a[pos-1] = tmp; |
|
|
|
p--; |
|
|
|
|
|
|
|
|
|
|
|
if (pos > 1){ |
|
|
|
|
|
|
|
if (last == 0){ |
|
|
|
|
|
|
|
last = pos; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
pos --; |
|
|
|
|
|
|
|
}else{ |
|
|
|
|
|
|
|
pos ++; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// int p = 0;
|
|
|
|
|
|
|
|
// int l = a.length;
|
|
|
|
|
|
|
|
// while (p < l) {
|
|
|
|
|
|
|
|
// int pm1 = p - 1;
|
|
|
|
|
|
|
|
// if (p == 0 || comp.compare(a[p], a[pm1]) >= 0) {
|
|
|
|
|
|
|
|
// p++;
|
|
|
|
|
|
|
|
// } else {
|
|
|
|
|
|
|
|
// Object t = a[p];
|
|
|
|
|
|
|
|
// a[p] = a[pm1];
|
|
|
|
|
|
|
|
// a[pm1] = t;
|
|
|
|
|
|
|
|
// p--;
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// }
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private static void test(Float[] original, Float[] sorted, Comparator<Float> ic){ |
|
|
|
private static void test(Float[] original, Float[] sorted, Comparator<Float> ic) { |
|
|
|
for (int i = 0; i < 1000000; i++){ |
|
|
|
long time, dt; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
time = System.nanoTime(); |
|
|
|
|
|
|
|
for (int i = 0; i < 1000000; i++) { |
|
|
|
System.arraycopy(original, 0, sorted, 0, original.length); |
|
|
|
System.arraycopy(original, 0, sorted, 0, original.length); |
|
|
|
gsort(sorted, ic); |
|
|
|
gsort(sorted, ic); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
dt = System.nanoTime() - time; |
|
|
|
|
|
|
|
System.out.println("GSort " + (dt/1000000.0) + " ms"); |
|
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < 1000000; i++){ |
|
|
|
time = System.nanoTime(); |
|
|
|
|
|
|
|
for (int i = 0; i < 1000000; i++) { |
|
|
|
System.arraycopy(original, 0, sorted, 0, original.length); |
|
|
|
System.arraycopy(original, 0, sorted, 0, original.length); |
|
|
|
qsort(sorted, ic); |
|
|
|
qsort(sorted, ic); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
dt = System.nanoTime() - time; |
|
|
|
|
|
|
|
System.out.println("QSort " + (dt/1000000.0) + " ms"); |
|
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < 1000000; i++){ |
|
|
|
time = System.nanoTime(); |
|
|
|
|
|
|
|
for (int i = 0; i < 1000000; i++) { |
|
|
|
System.arraycopy(original, 0, sorted, 0, original.length); |
|
|
|
System.arraycopy(original, 0, sorted, 0, original.length); |
|
|
|
msort(original, sorted, ic); |
|
|
|
msort(original, sorted, ic); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
dt = System.nanoTime() - time; |
|
|
|
for (int i = 0; i < 1000000; i++){ |
|
|
|
System.out.println("MSort " + (dt/1000000.0) + " ms"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
time = System.nanoTime(); |
|
|
|
|
|
|
|
for (int i = 0; i < 1000000; i++) { |
|
|
|
System.arraycopy(original, 0, sorted, 0, original.length); |
|
|
|
System.arraycopy(original, 0, sorted, 0, original.length); |
|
|
|
Arrays.sort(sorted, ic); |
|
|
|
Arrays.sort(sorted, ic); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
dt = System.nanoTime() - time; |
|
|
|
|
|
|
|
System.out.println("ASort " + (dt/1000000.0) + " ms"); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public static void main(String[] args){ |
|
|
|
public static void main(String[] args) { |
|
|
|
Comparator<Float> ic = new Comparator<Float>() { |
|
|
|
Comparator<Float> ic = new Comparator<Float>() { |
|
|
|
|
|
|
|
|
|
|
|
public int compare(Float o1, Float o2) { |
|
|
|
public int compare(Float o1, Float o2) { |
|
|
|
return (int) (o1 - o2); |
|
|
|
return (int) (o1 - o2); |
|
|
|
} |
|
|
|
} |
|
|
|
}; |
|
|
|
}; |
|
|
|
Float[] original = new Float[]{ 2f, 1f, 5f, 3f, 4f, 6f, 8f, 9f, |
|
|
|
Float[] original = new Float[]{2f, 1f, 5f, 3f, 4f, 6f, 8f, 9f, |
|
|
|
11f, 10f, 12f, 13f, 14f, 15f, 7f, 19f, 20f, 18f, 16f, 17f, |
|
|
|
11f, 10f, 12f, 13f, 14f, 15f, 7f, 19f, 20f, 18f, 16f, 17f, |
|
|
|
21f, 23f, 22f, 24f, 25f, 27f, 26f, 29f, 28f, 30f, 31f}; |
|
|
|
21f, 23f, 22f, 24f, 25f, 27f, 26f, 29f, 28f, 30f, 31f}; |
|
|
|
Float[] sorted = new Float[original.length]; |
|
|
|
Float[] sorted = new Float[original.length]; |
|
|
|
|
|
|
|
|
|
|
|
while (true){ |
|
|
|
while (true) { |
|
|
|
test(original, sorted, ic); |
|
|
|
test(original, sorted, ic); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -98,9 +172,8 @@ public class SortUtil |
|
|
|
/** |
|
|
|
/** |
|
|
|
* Quick sorts the supplied array using the specified comparator. |
|
|
|
* Quick sorts the supplied array using the specified comparator. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public static void qsort (Object[] a, Comparator comp) |
|
|
|
public static void qsort(Object[] a, Comparator comp) { |
|
|
|
{ |
|
|
|
qsort(a, 0, a.length - 1, comp); |
|
|
|
qsort(a, 0, a.length-1, comp); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
@ -110,8 +183,7 @@ public class SortUtil |
|
|
|
* @param hi0 the index of the highest element to include in the sort. |
|
|
|
* @param hi0 the index of the highest element to include in the sort. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
@SuppressWarnings("unchecked") |
|
|
|
@SuppressWarnings("unchecked") |
|
|
|
public static void qsort (Object[] a, int lo0, int hi0, Comparator comp) |
|
|
|
public static void qsort(Object[] a, int lo0, int hi0, Comparator comp) { |
|
|
|
{ |
|
|
|
|
|
|
|
// bail out if we're already done
|
|
|
|
// bail out if we're already done
|
|
|
|
if (hi0 <= lo0) { |
|
|
|
if (hi0 <= lo0) { |
|
|
|
return; |
|
|
|
return; |
|
|
@ -122,16 +194,18 @@ public class SortUtil |
|
|
|
if (hi0 - lo0 == 1) { |
|
|
|
if (hi0 - lo0 == 1) { |
|
|
|
// if they're not already sorted, swap them
|
|
|
|
// if they're not already sorted, swap them
|
|
|
|
if (comp.compare(a[hi0], a[lo0]) < 0) { |
|
|
|
if (comp.compare(a[hi0], a[lo0]) < 0) { |
|
|
|
t = a[lo0]; a[lo0] = a[hi0]; a[hi0] = t; |
|
|
|
t = a[lo0]; |
|
|
|
|
|
|
|
a[lo0] = a[hi0]; |
|
|
|
|
|
|
|
a[hi0] = t; |
|
|
|
} |
|
|
|
} |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// the middle element in the array is our partitioning element
|
|
|
|
// the middle element in the array is our partitioning element
|
|
|
|
Object mid = a[(lo0 + hi0)/2]; |
|
|
|
Object mid = a[(lo0 + hi0) / 2]; |
|
|
|
|
|
|
|
|
|
|
|
// set up our partitioning boundaries
|
|
|
|
// set up our partitioning boundaries
|
|
|
|
int lo = lo0-1, hi = hi0+1; |
|
|
|
int lo = lo0 - 1, hi = hi0 + 1; |
|
|
|
|
|
|
|
|
|
|
|
// loop through the array until indices cross
|
|
|
|
// loop through the array until indices cross
|
|
|
|
for (;;) { |
|
|
|
for (;;) { |
|
|
@ -145,7 +219,9 @@ public class SortUtil |
|
|
|
|
|
|
|
|
|
|
|
// swap the two elements or bail out of the loop
|
|
|
|
// swap the two elements or bail out of the loop
|
|
|
|
if (hi > lo) { |
|
|
|
if (hi > lo) { |
|
|
|
t = a[lo]; a[lo] = a[hi]; a[hi] = t; |
|
|
|
t = a[lo]; |
|
|
|
|
|
|
|
a[lo] = a[hi]; |
|
|
|
|
|
|
|
a[hi] = t; |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
break; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
@ -153,19 +229,18 @@ public class SortUtil |
|
|
|
|
|
|
|
|
|
|
|
// if the right index has not reached the left side of array
|
|
|
|
// if the right index has not reached the left side of array
|
|
|
|
// must now sort the left partition
|
|
|
|
// must now sort the left partition
|
|
|
|
if (lo0 < lo-1) { |
|
|
|
if (lo0 < lo - 1) { |
|
|
|
qsort(a, lo0, lo-1, comp); |
|
|
|
qsort(a, lo0, lo - 1, comp); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// if the left index has not reached the right side of array
|
|
|
|
// if the left index has not reached the right side of array
|
|
|
|
// must now sort the right partition
|
|
|
|
// must now sort the right partition
|
|
|
|
if (hi+1 < hi0) { |
|
|
|
if (hi + 1 < hi0) { |
|
|
|
qsort(a, hi+1, hi0, comp); |
|
|
|
qsort(a, hi + 1, hi0, comp); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public static void qsort (int[] a, int lo0, int hi0, Comparator comp) |
|
|
|
public static void qsort(int[] a, int lo0, int hi0, Comparator comp) { |
|
|
|
{ |
|
|
|
|
|
|
|
// bail out if we're already done
|
|
|
|
// bail out if we're already done
|
|
|
|
if (hi0 <= lo0) { |
|
|
|
if (hi0 <= lo0) { |
|
|
|
return; |
|
|
|
return; |
|
|
@ -176,16 +251,18 @@ public class SortUtil |
|
|
|
if (hi0 - lo0 == 1) { |
|
|
|
if (hi0 - lo0 == 1) { |
|
|
|
// if they're not already sorted, swap them
|
|
|
|
// if they're not already sorted, swap them
|
|
|
|
if (comp.compare(a[hi0], a[lo0]) < 0) { |
|
|
|
if (comp.compare(a[hi0], a[lo0]) < 0) { |
|
|
|
t = a[lo0]; a[lo0] = a[hi0]; a[hi0] = t; |
|
|
|
t = a[lo0]; |
|
|
|
|
|
|
|
a[lo0] = a[hi0]; |
|
|
|
|
|
|
|
a[hi0] = t; |
|
|
|
} |
|
|
|
} |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// the middle element in the array is our partitioning element
|
|
|
|
// the middle element in the array is our partitioning element
|
|
|
|
int mid = a[(lo0 + hi0)/2]; |
|
|
|
int mid = a[(lo0 + hi0) / 2]; |
|
|
|
|
|
|
|
|
|
|
|
// set up our partitioning boundaries
|
|
|
|
// set up our partitioning boundaries
|
|
|
|
int lo = lo0-1, hi = hi0+1; |
|
|
|
int lo = lo0 - 1, hi = hi0 + 1; |
|
|
|
|
|
|
|
|
|
|
|
// loop through the array until indices cross
|
|
|
|
// loop through the array until indices cross
|
|
|
|
for (;;) { |
|
|
|
for (;;) { |
|
|
@ -199,7 +276,9 @@ public class SortUtil |
|
|
|
|
|
|
|
|
|
|
|
// swap the two elements or bail out of the loop
|
|
|
|
// swap the two elements or bail out of the loop
|
|
|
|
if (hi > lo) { |
|
|
|
if (hi > lo) { |
|
|
|
t = a[lo]; a[lo] = a[hi]; a[hi] = t; |
|
|
|
t = a[lo]; |
|
|
|
|
|
|
|
a[lo] = a[hi]; |
|
|
|
|
|
|
|
a[hi] = t; |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
break; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
@ -207,85 +286,67 @@ public class SortUtil |
|
|
|
|
|
|
|
|
|
|
|
// if the right index has not reached the left side of array
|
|
|
|
// if the right index has not reached the left side of array
|
|
|
|
// must now sort the left partition
|
|
|
|
// must now sort the left partition
|
|
|
|
if (lo0 < lo-1) { |
|
|
|
if (lo0 < lo - 1) { |
|
|
|
qsort(a, lo0, lo-1, comp); |
|
|
|
qsort(a, lo0, lo - 1, comp); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// if the left index has not reached the right side of array
|
|
|
|
// if the left index has not reached the right side of array
|
|
|
|
// must now sort the right partition
|
|
|
|
// must now sort the right partition
|
|
|
|
if (hi+1 < hi0) { |
|
|
|
if (hi + 1 < hi0) { |
|
|
|
qsort(a, hi+1, hi0, comp); |
|
|
|
qsort(a, hi + 1, hi0, comp); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Merge sorts the supplied array using the specified comparator. |
|
|
|
* Merge sort |
|
|
|
* |
|
|
|
|
|
|
|
* @param src contains the elements to be sorted. |
|
|
|
|
|
|
|
* @param dest must contain the same values as the src array. |
|
|
|
|
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public static void msort (Object[] src, Object[] dest, Comparator comp) |
|
|
|
public static void msort(Object[] src, Object[] dest, Comparator comp){ |
|
|
|
{ |
|
|
|
msort(src, dest, 0, src.length - 1, comp); |
|
|
|
msort(src, dest, 0, src.length, 0, comp); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Merge sorts the supplied array using the specified comparator. |
|
|
|
* Merge sort |
|
|
|
* |
|
|
|
* |
|
|
|
* @param src contains the elements to be sorted. |
|
|
|
* @param src Source array |
|
|
|
* @param dest must contain the same values as the src array. |
|
|
|
* @param dest Destination array |
|
|
|
|
|
|
|
* @param low Index of beginning element |
|
|
|
|
|
|
|
* @param high Index of end element |
|
|
|
|
|
|
|
* @param comp Comparator |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public static void msort (Object[] src, Object[] dest, int low, int high, |
|
|
|
public static void msort(Object[] src, Object[] dest, int low, int high, |
|
|
|
Comparator comp) |
|
|
|
Comparator comp) { |
|
|
|
{ |
|
|
|
if(low < high) { |
|
|
|
msort(src, dest, low, high, 0, comp); |
|
|
|
int center = (low + high) / 2; |
|
|
|
|
|
|
|
msort(src, dest, low, center, comp); |
|
|
|
|
|
|
|
msort(src, dest, center + 1, high, comp); |
|
|
|
|
|
|
|
merge(src, dest, low, center + 1, high, comp); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** Implements the actual merge sort. */ |
|
|
|
private static void merge(Object[] src, Object[] dest, |
|
|
|
@SuppressWarnings("unchecked") |
|
|
|
int low, int middle, int high, Comparator comp) { |
|
|
|
protected static void msort (Object[] src, Object[] dest, int low, |
|
|
|
int leftEnd = middle - 1; |
|
|
|
int high, int offset, Comparator comp) |
|
|
|
int pos = low; |
|
|
|
{ |
|
|
|
int numElements = high - low + 1; |
|
|
|
// use an insertion sort on small arrays
|
|
|
|
|
|
|
|
int length = high - low; |
|
|
|
while (low <= leftEnd && middle <= high) { |
|
|
|
if (length < INSERTION_SORT_THRESHOLD) { |
|
|
|
if (comp.compare(src[low], src[middle]) <= 0) { |
|
|
|
for (int ii = low; ii < high; ii++) { |
|
|
|
dest[pos++] = src[low++]; |
|
|
|
for (int jj = ii; |
|
|
|
} else { |
|
|
|
jj > low && comp.compare(dest[jj-1], dest[jj]) > 0; jj--) { |
|
|
|
dest[pos++] = src[middle++]; |
|
|
|
Object temp = dest[jj]; |
|
|
|
|
|
|
|
dest[jj] = dest[jj-1]; |
|
|
|
|
|
|
|
dest[jj-1] = temp; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
return; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// recursively sort each half of dest into src
|
|
|
|
|
|
|
|
int destLow = low, destHigh = high; |
|
|
|
|
|
|
|
low += offset; |
|
|
|
|
|
|
|
high += offset; |
|
|
|
|
|
|
|
int mid = (low + high) >> 1; |
|
|
|
|
|
|
|
msort(dest, src, low, mid, -offset, comp); |
|
|
|
|
|
|
|
msort(dest, src, mid, high, -offset, comp); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// if the list is already sorted, just copy from src to dest; this
|
|
|
|
|
|
|
|
// optimization results in faster sorts for nearly ordered lists
|
|
|
|
|
|
|
|
if (comp.compare(src[mid-1], src[mid]) <= 0) { |
|
|
|
|
|
|
|
System.arraycopy(src, low, dest, destLow, length); |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// merge the sorted halves (now in src) into dest
|
|
|
|
while (low <= leftEnd) { |
|
|
|
for (int ii = destLow, pp = low, qq = mid; ii < destHigh; ii++) { |
|
|
|
dest[pos++] = src[low++]; |
|
|
|
if (qq >= high || pp < mid && comp.compare(src[pp], src[qq]) <= 0) { |
|
|
|
|
|
|
|
dest[ii] = src[pp++]; |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
dest[ii] = src[qq++]; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** The size at or below which we will use insertion sort because it's |
|
|
|
while (middle <= high) { |
|
|
|
* probably faster. */ |
|
|
|
dest[pos++] = src[middle++]; |
|
|
|
private static final int INSERTION_SORT_THRESHOLD = 7; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < numElements; i++, high--) { |
|
|
|
|
|
|
|
src[high] = dest[high]; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|