mirror of
https://gitlab.uni-marburg.de/langbeid/powersort.git
synced 2025-01-21 19:50:35 +01:00
Changed FasterFinnSort to use the PowerSort merge policy
This commit is contained in:
parent
c8bed52bf6
commit
4268315f06
@ -28,6 +28,8 @@ package de.uni_marburg.powersort.FinnSort;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
import static java.lang.Math.pow;
|
||||
|
||||
/**
|
||||
* A stable, adaptive, iterative mergesort that requires far fewer than
|
||||
* n lg(n) comparisons when running on partially sorted arrays, while
|
||||
@ -61,7 +63,7 @@ import java.util.Comparator;
|
||||
*
|
||||
* @author Josh Bloch
|
||||
*/
|
||||
class FasterFinnSort<T> {
|
||||
public class FasterFinnSort<T> {
|
||||
/**
|
||||
* This is the minimum sized sequence that will be merged. Shorter
|
||||
* sequences will be lengthened by calling binarySort. If the entire
|
||||
@ -135,6 +137,7 @@ class FasterFinnSort<T> {
|
||||
private int stackSize = 0; // Number of pending runs on stack
|
||||
private final int[] runBase;
|
||||
private final int[] runLen;
|
||||
private final int[] runPower;
|
||||
|
||||
/**
|
||||
* Creates a TimSort instance to maintain the state of an ongoing sort.
|
||||
@ -186,6 +189,7 @@ class FasterFinnSort<T> {
|
||||
len < 119151 ? 24 : 49);
|
||||
runBase = new int[stackLen];
|
||||
runLen = new int[stackLen];
|
||||
runPower = new int[stackLen];
|
||||
}
|
||||
|
||||
/*
|
||||
@ -209,7 +213,7 @@ class FasterFinnSort<T> {
|
||||
* @param workLen usable size of work array
|
||||
* @since 1.8
|
||||
*/
|
||||
static <T> void sort(T[] a, int lo, int hi, Comparator<? super T> c,
|
||||
public static <T> void sort(T[] a, int lo, int hi, Comparator<? super T> c,
|
||||
T[] work, int workBase, int workLen) {
|
||||
assert c != null && a != null && lo >= 0 && lo <= hi && hi <= a.length;
|
||||
|
||||
@ -243,7 +247,7 @@ class FasterFinnSort<T> {
|
||||
}
|
||||
|
||||
// Push run onto pending-run stack, and maybe merge
|
||||
ts.pushRun(lo, runLen);
|
||||
ts.pushRun(lo, runLen, hi - lo);
|
||||
ts.mergeCollapse();
|
||||
|
||||
// Advance to find next run
|
||||
@ -415,9 +419,10 @@ class FasterFinnSort<T> {
|
||||
* @param runBase index of the first element in the run
|
||||
* @param runLen the number of elements in the run
|
||||
*/
|
||||
private void pushRun(int runBase, int runLen) {
|
||||
private void pushRun(int runBase, int runLen, int rangeSize) {
|
||||
this.runBase[stackSize] = runBase;
|
||||
this.runLen[stackSize] = runLen;
|
||||
this.runPower[stackSize] = power(stackSize, rangeSize);
|
||||
stackSize++;
|
||||
}
|
||||
|
||||
@ -440,16 +445,29 @@ class FasterFinnSort<T> {
|
||||
private void mergeCollapse() {
|
||||
while (stackSize > 1) {
|
||||
int n = stackSize - 2;
|
||||
if (n > 0 && runLen[n-1] <= runLen[n] + runLen[n+1] ||
|
||||
n > 1 && runLen[n-2] <= runLen[n] + runLen[n-1]) {
|
||||
if (runLen[n - 1] < runLen[n + 1])
|
||||
n--;
|
||||
} else if (n < 0 || runLen[n] > runLen[n + 1]) {
|
||||
if (n > 0 && runPower[n + 1] < runPower[n]) {
|
||||
mergeAt(n);
|
||||
} else {
|
||||
break; // Invariant is established
|
||||
}
|
||||
mergeAt(n);
|
||||
}
|
||||
}
|
||||
|
||||
private int power(int stackSize, int rangeSize) {
|
||||
if (stackSize == 0)
|
||||
return 0;
|
||||
|
||||
int n_1 = this.runLen[stackSize - 1];
|
||||
int n_2 = this.runLen[stackSize];
|
||||
double a = ((double) this.runBase[stackSize - 1] + 0.5d * n_1 - 1d) / rangeSize;
|
||||
double b = ((double) this.runBase[stackSize] + 0.5d * n_2 - 1d) / rangeSize;
|
||||
int l = 0;
|
||||
while ((int) (a * pow(2, l)) == (int) (b * pow(2 ,l))) {
|
||||
l++;
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
||||
/*
|
||||
Backup mergeCollapse() von TimSort:
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user