Performs a sort on the section of the array between the given indices using a mergesort with exponential search algorithm (in which the merge is performed by exponential search). n log(n) performance is guaranteed and in the average case it will be faster then any mergesort in which the merge is per
(Object[] in, Object[] out, int start,
int end)
| 2637 | * the end index + 1 |
| 2638 | */ |
| 2639 | @SuppressWarnings("unchecked") |
| 2640 | private static void mergeSort(Object[] in, Object[] out, int start, |
| 2641 | int end) { |
| 2642 | int len = end - start; |
| 2643 | |
| 2644 | Object o = in[start]; |
| 2645 | // use insertion sort for small arrays |
| 2646 | if (len <= SIMPLE_LENGTH) { |
| 2647 | for (int i = start + 1; i < end; i++) { |
| 2648 | java.lang.Comparable<Object> current = |
| 2649 | (java.lang.Comparable<Object>) out[i]; |
| 2650 | Object prev = out[i - 1]; |
| 2651 | if (current.compareTo(prev) < 0) { |
| 2652 | int j = i; |
| 2653 | do { |
| 2654 | out[j--] = prev; |
| 2655 | } while (j > start |
| 2656 | && current.compareTo(prev = out[j - 1]) < 0); |
| 2657 | out[j] = current; |
| 2658 | } |
| 2659 | } |
| 2660 | return; |
| 2661 | } |
| 2662 | int med = (end + start) >>> 1; |
| 2663 | mergeSort(out, in, start, med); |
| 2664 | mergeSort(out, in, med, end); |
| 2665 | |
| 2666 | // merging |
| 2667 | |
| 2668 | // if arrays are already sorted - no merge |
| 2669 | if (((java.lang.Comparable<Object>) in[med - 1]).compareTo(in[med]) <= 0) { |
| 2670 | System.arraycopy(in, start, out, start, len); |
| 2671 | return; |
| 2672 | } |
| 2673 | int r = med, i = start; |
| 2674 | |
| 2675 | // use merging with exponential search |
| 2676 | do { |
| 2677 | java.lang.Comparable<Object> fromVal = (java.lang.Comparable<Object>) in[start]; |
| 2678 | java.lang.Comparable<Object> rVal = (java.lang.Comparable<Object>) in[r]; |
| 2679 | if (fromVal.compareTo(rVal) <= 0) { |
| 2680 | int l_1 = find(in, rVal, -1, start + 1, med - 1); |
| 2681 | int toCopy = l_1 - start + 1; |
| 2682 | System.arraycopy(in, start, out, i, toCopy); |
| 2683 | i += toCopy; |
| 2684 | out[i++] = rVal; |
| 2685 | r++; |
| 2686 | start = l_1 + 1; |
| 2687 | } else { |
| 2688 | int r_1 = find(in, fromVal, 0, r + 1, end - 1); |
| 2689 | int toCopy = r_1 - r + 1; |
| 2690 | System.arraycopy(in, r, out, i, toCopy); |
| 2691 | i += toCopy; |
| 2692 | out[i++] = fromVal; |
| 2693 | start++; |
| 2694 | r = r_1 + 1; |
| 2695 | } |
| 2696 | } while ((end - r) > 0 && (med - start) > 0); |