public class TimSort<T>
extends java.lang.Object
Modifier and Type | Field and Description |
---|---|
private T[] |
a
The array being sorted.
|
private java.util.Comparator<? super T> |
c
The comparator for this sort.
|
private static int |
INITIAL_TMP_STORAGE_LENGTH
Maximum initial size of tmp array, which is used for merging.
|
private static int |
MIN_GALLOP
When we get into galloping mode, we stay there until both runs win less
often than MIN_GALLOP consecutive times.
|
private static int |
MIN_MERGE
This is the minimum sized sequence that will be merged.
|
private int |
minGallop
This controls when we get *into* galloping mode.
|
private int[] |
runBase |
private int[] |
runLen |
private int |
stackSize
A stack of pending runs yet to be merged.
|
private T[] |
tmp
Temp storage for merges.
|
Modifier | Constructor and Description |
---|---|
private |
TimSort(T[] a,
java.util.Comparator<? super T> c)
Creates a TimSort instance to maintain the state of an ongoing sort.
|
Modifier and Type | Method and Description |
---|---|
private static <T> void |
binarySort(T[] a,
int lo,
int hi,
int start,
java.util.Comparator<? super T> c)
Sorts the specified portion of the specified array using a binary
insertion sort.
|
private static <T> int |
countRunAndMakeAscending(T[] a,
int lo,
int hi,
java.util.Comparator<? super T> c)
Returns the length of the run beginning at the specified position in
the specified array and reverses the run if it is descending (ensuring
that the run will always be ascending when the method returns).
|
private T[] |
ensureCapacity(int minCapacity)
Ensures that the external array tmp has at least the specified
number of elements, increasing its size if necessary.
|
private static <T> int |
gallopLeft(T key,
T[] a,
int base,
int len,
int hint,
java.util.Comparator<? super T> c)
Locates the position at which to insert the specified key into the
specified sorted range; if the range contains an element equal to key,
returns the index of the leftmost equal element.
|
private static <T> int |
gallopRight(T key,
T[] a,
int base,
int len,
int hint,
java.util.Comparator<? super T> c)
Like gallopLeft, except that if the range contains an element equal to
key, gallopRight returns the index after the rightmost equal element.
|
private void |
mergeAt(int i)
Merges the two runs at stack indices i and i+1.
|
private void |
mergeCollapse()
Examines the stack of runs waiting to be merged and merges adjacent runs
until the stack invariants are reestablished:
1.
|
private void |
mergeForceCollapse()
Merges all runs on the stack until only one remains.
|
private void |
mergeHi(int base1,
int len1,
int base2,
int len2)
Like mergeLo, except that this method should be called only if
len1 >= len2; mergeLo should be called if len1 <= len2.
|
private void |
mergeLo(int base1,
int len1,
int base2,
int len2)
Merges two adjacent runs in place, in a stable fashion.
|
private static int |
minRunLength(int n)
Returns the minimum acceptable run length for an array of the specified
length.
|
private void |
pushRun(int runBase,
int runLen)
Pushes the specified run onto the pending-run stack.
|
private static void |
rangeCheck(int arrayLen,
int fromIndex,
int toIndex)
Checks that fromIndex and toIndex are in range, and throws an
appropriate exception if they aren't.
|
private static void |
reverseRange(java.lang.Object[] a,
int lo,
int hi)
Reverse the specified range of the specified array.
|
static <T> void |
sort(T[] a,
java.util.Comparator<? super T> c) |
static <T> void |
sort(T[] a,
int lo,
int hi,
java.util.Comparator<? super T> c) |
private static final int MIN_MERGE
minRunLength(int)
computation.
If you decrease this constant, you must change the stackLen
computation in the TimSort constructor, or you risk an
ArrayOutOfBounds exception. See listsort.txt for a discussion
of the minimum stack length required as a function of the length
of the array being sorted and the minimum merge sequence length.private final T[] a
private final java.util.Comparator<? super T> c
private static final int MIN_GALLOP
private int minGallop
private static final int INITIAL_TMP_STORAGE_LENGTH
private T[] tmp
private int stackSize
private final int[] runBase
private final int[] runLen
public static <T> void sort(T[] a, java.util.Comparator<? super T> c)
public static <T> void sort(T[] a, int lo, int hi, java.util.Comparator<? super T> c)
private static <T> void binarySort(T[] a, int lo, int hi, int start, java.util.Comparator<? super T> c)
lo
, inclusive, to start
,
exclusive are already sorted.a
- the array in which a range is to be sortedlo
- the index of the first element in the range to be sortedhi
- the index after the last element in the range to be sortedstart
- the index of the first element in the range that is
not already known to be sorted (@code lo <= start <= hi}c
- comparator to used for the sortprivate static <T> int countRunAndMakeAscending(T[] a, int lo, int hi, java.util.Comparator<? super T> c)
a
- the array in which a run is to be counted and possibly reversedlo
- index of the first element in the runhi
- index after the last element that may be contained in the run.
It is required that @code{lo < hi}.c
- the comparator to used for the sortprivate static void reverseRange(java.lang.Object[] a, int lo, int hi)
a
- the array in which a range is to be reversedlo
- the index of the first element in the range to be reversedhi
- the index after the last element in the range to be reversedprivate static int minRunLength(int n)
binarySort(T[], int, int, int, java.util.Comparator<? super T>)
.
Roughly speaking, the computation is:
If n < MIN_MERGE, return n (it's too small to bother with fancy stuff).
Else if n is an exact power of 2, return MIN_MERGE/2.
Else return an int k, MIN_MERGE/2 <= k <= MIN_MERGE, such that n/k
is close to, but strictly less than, an exact power of 2.
For the rationale, see listsort.txt.n
- the length of the array to be sortedprivate void pushRun(int runBase, int runLen)
runBase
- index of the first element in the runrunLen
- the number of elements in the runprivate void mergeCollapse()
private void mergeForceCollapse()
private void mergeAt(int i)
i
- stack index of the first of the two runs to mergeprivate static <T> int gallopLeft(T key, T[] a, int base, int len, int hint, java.util.Comparator<? super T> c)
key
- the key whose insertion point to search fora
- the array in which to searchbase
- the index of the first element in the rangelen
- the length of the range; must be > 0hint
- the index at which to begin the search, 0 <= hint < n.
The closer hint is to the result, the faster this method will run.c
- the comparator used to order the range, and to searchprivate static <T> int gallopRight(T key, T[] a, int base, int len, int hint, java.util.Comparator<? super T> c)
key
- the key whose insertion point to search fora
- the array in which to searchbase
- the index of the first element in the rangelen
- the length of the range; must be > 0hint
- the index at which to begin the search, 0 <= hint < n.
The closer hint is to the result, the faster this method will run.c
- the comparator used to order the range, and to searchprivate void mergeLo(int base1, int len1, int base2, int len2)
base1
- index of first element in first run to be mergedlen1
- length of first run to be merged (must be > 0)base2
- index of first element in second run to be merged
(must be aBase + aLen)len2
- length of second run to be merged (must be > 0)private void mergeHi(int base1, int len1, int base2, int len2)
base1
- index of first element in first run to be mergedlen1
- length of first run to be merged (must be > 0)base2
- index of first element in second run to be merged
(must be aBase + aLen)len2
- length of second run to be merged (must be > 0)private T[] ensureCapacity(int minCapacity)
minCapacity
- the minimum required capacity of the tmp arrayprivate static void rangeCheck(int arrayLen, int fromIndex, int toIndex)
arrayLen
- the length of the arrayfromIndex
- the index of the first element of the rangetoIndex
- the index after the last element of the rangejava.lang.IllegalArgumentException
- if fromIndex > toIndexjava.lang.ArrayIndexOutOfBoundsException
- if fromIndex < 0
or toIndex > arrayLen