Changed FinnSort to merge before pushing

This commit is contained in:
finnm 2025-03-07 14:58:17 +01:00
parent 03de85aedb
commit 2e1ef0798f
3 changed files with 19 additions and 19 deletions

View File

@ -233,8 +233,10 @@ public class FasterFinnSort<T> {
}
// Push run onto pending-run stack, and maybe merge
fs.pushRun(lo, runLen);
fs.mergeCollapse();
int p = fs.power(fs.stackSize, runLen);
fs.mergeCollapse(p);
fs.pushRun(lo, runLen, p);
// Advance to find next run
lo += runLen;
@ -405,10 +407,10 @@ public class FasterFinnSort<T> {
* @param runBase index of the first element in the run
* @param runLen the number of elements in the run
*/
void pushRun(int runBase, int runLen) {
void pushRun(int runBase, int runLen, int power) {
this.runBase[stackSize] = runBase;
this.runLen[stackSize] = runLen;
this.runPower[stackSize] = power(stackSize);
this.runPower[stackSize] = power;
stackSize++;
}
@ -428,10 +430,10 @@ public class FasterFinnSort<T> {
* the analysis in "On the Worst-Case Complexity of TimSort" by
* Nicolas Auger, Vincent Jug, Cyril Nicaud, and Carine Pivoteau.
*/
void mergeCollapse() {
void mergeCollapse(int power) {
while (stackSize > 1) {
if (runPower[stackSize - 1] < runPower[stackSize - 2]) {
mergeAt(stackSize - 3);
if (power < runPower[stackSize - 1]) {
mergeAt(stackSize - 2);
} else {
break; // Invariant is established
}
@ -450,7 +452,7 @@ public class FasterFinnSort<T> {
return Integer.numberOfLeadingZeros(a ^ b);
}
*/
int power(int stackSize) {
int power(int stackSize, int runLen) {
/*
System.out.println(Arrays.toString(runBase));
System.out.println(Arrays.toString(runLen));
@ -463,7 +465,7 @@ public class FasterFinnSort<T> {
return 0;
int n_1 = this.runLen[stackSize - 1];
int n_2 = this.runLen[stackSize];
int n_2 = runLen;
int a = 2 * this.runBase[stackSize - 1] + n_1;
int b = a + n_1 + n_2;
@ -573,12 +575,6 @@ public class FasterFinnSort<T> {
stackSize--;
runLen[i] = len1 + len2;
// @TODO: Check power before pushing the run
runLen[i + 1] = runLen[i + 2];
runBase[i + 1] = runBase[i + 2];
runPower[i + 1] = runPower[i + 2];
//runPower[i] = power(i);
/*
* Find where the first element of run2 goes in run1. Prior elements
* in run1 can be ignored (because they're already in place).

View File

@ -36,7 +36,7 @@ public class FasterFinnSortMockitoTest {
// Capture calculated power values.
final ResultCaptor<Integer> resultCaptor = new ResultCaptor<>();
doAnswer(resultCaptor).when(spiedFfs).power(anyInt());
doAnswer(resultCaptor).when(spiedFfs).power(anyInt(), anyInt());
sort(a, spiedFfs);
@ -53,6 +53,6 @@ public class FasterFinnSortMockitoTest {
// Don't sort short array with `binarySort()`
boolean forcePowersortShortArray = true;
FasterFinnSortWrapper.sort(a, 0, a.length, NaturalOrder.INSTANCE, null, 0, 0, ffs, forcePowersortShortArray);
//FasterFinnSortWrapper.sort(a, 0, a.length, NaturalOrder.INSTANCE, null, 0, 0, ffs, forcePowersortShortArray);
}
}

View File

@ -1,3 +1,4 @@
/*
package de.uni_marburg.powersort.FinnSort;
import java.util.Comparator;
@ -11,7 +12,7 @@ public class FasterFinnSortWrapper {
* Copy of `FasterFinnSort.java`. Param `ts` has been added to allow dependency injection for testing.
*
* @param fs: If non-null, the creation of `ts` with `new FasterFinnSort<>(a, c, work, workBase, workLen)` in this methods body is skipped. Instead, the given `ts` is used.
*/
*
public static <T> void sort(T[] a, int lo, int hi, Comparator<? super T> c,
T[] work, int workBase, int workLen,
FasterFinnSort<T> fs, boolean forcePowersortShortArray) {
@ -32,7 +33,7 @@ public class FasterFinnSortWrapper {
* March over the array once, left to right, finding natural runs,
* extending short natural runs to minRun elements, and merging runs
* to maintain stack invariant.
*/
*
if (fs == null) fs = new FasterFinnSort<>(a, c, work, workBase, workLen, hi - lo);
int minRun = fs.minRunLength(nRemaining);
do {
@ -61,3 +62,6 @@ public class FasterFinnSortWrapper {
assert fs.stackSize == 1;
}
}
*/