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 java.util.Comparator;
|
||||||
|
|
||||||
|
import static java.lang.Math.pow;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A stable, adaptive, iterative mergesort that requires far fewer than
|
* A stable, adaptive, iterative mergesort that requires far fewer than
|
||||||
* n lg(n) comparisons when running on partially sorted arrays, while
|
* n lg(n) comparisons when running on partially sorted arrays, while
|
||||||
@ -61,7 +63,7 @@ import java.util.Comparator;
|
|||||||
*
|
*
|
||||||
* @author Josh Bloch
|
* @author Josh Bloch
|
||||||
*/
|
*/
|
||||||
class FasterFinnSort<T> {
|
public class FasterFinnSort<T> {
|
||||||
/**
|
/**
|
||||||
* This is the minimum sized sequence that will be merged. Shorter
|
* This is the minimum sized sequence that will be merged. Shorter
|
||||||
* sequences will be lengthened by calling binarySort. If the entire
|
* 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 int stackSize = 0; // Number of pending runs on stack
|
||||||
private final int[] runBase;
|
private final int[] runBase;
|
||||||
private final int[] runLen;
|
private final int[] runLen;
|
||||||
|
private final int[] runPower;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a TimSort instance to maintain the state of an ongoing sort.
|
* Creates a TimSort instance to maintain the state of an ongoing sort.
|
||||||
@ -186,6 +189,7 @@ class FasterFinnSort<T> {
|
|||||||
len < 119151 ? 24 : 49);
|
len < 119151 ? 24 : 49);
|
||||||
runBase = new int[stackLen];
|
runBase = new int[stackLen];
|
||||||
runLen = 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
|
* @param workLen usable size of work array
|
||||||
* @since 1.8
|
* @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) {
|
T[] work, int workBase, int workLen) {
|
||||||
assert c != null && a != null && lo >= 0 && lo <= hi && hi <= a.length;
|
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
|
// Push run onto pending-run stack, and maybe merge
|
||||||
ts.pushRun(lo, runLen);
|
ts.pushRun(lo, runLen, hi - lo);
|
||||||
ts.mergeCollapse();
|
ts.mergeCollapse();
|
||||||
|
|
||||||
// Advance to find next run
|
// Advance to find next run
|
||||||
@ -415,9 +419,10 @@ class FasterFinnSort<T> {
|
|||||||
* @param runBase index of the first element in the run
|
* @param runBase index of the first element in the run
|
||||||
* @param runLen the number of elements 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.runBase[stackSize] = runBase;
|
||||||
this.runLen[stackSize] = runLen;
|
this.runLen[stackSize] = runLen;
|
||||||
|
this.runPower[stackSize] = power(stackSize, rangeSize);
|
||||||
stackSize++;
|
stackSize++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -440,16 +445,29 @@ class FasterFinnSort<T> {
|
|||||||
private void mergeCollapse() {
|
private void mergeCollapse() {
|
||||||
while (stackSize > 1) {
|
while (stackSize > 1) {
|
||||||
int n = stackSize - 2;
|
int n = stackSize - 2;
|
||||||
if (n > 0 && runLen[n-1] <= runLen[n] + runLen[n+1] ||
|
if (n > 0 && runPower[n + 1] < runPower[n]) {
|
||||||
n > 1 && runLen[n-2] <= runLen[n] + runLen[n-1]) {
|
mergeAt(n);
|
||||||
if (runLen[n - 1] < runLen[n + 1])
|
} else {
|
||||||
n--;
|
|
||||||
} else if (n < 0 || runLen[n] > runLen[n + 1]) {
|
|
||||||
break; // Invariant is established
|
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:
|
Backup mergeCollapse() von TimSort:
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user