This commit is contained in:
Ambili Jacob 2025-03-13 11:29:15 +01:00
parent 691d7eb0ac
commit 89c0ca10c7

View File

@ -1,13 +1,12 @@
package de.uni_marburg.powersort.sort;
import java.util.Comparator;
import java.util.Stack;
import java.util.*;
import java.util.stream.Collectors;
public class ASort {
private static class Run {
int start, end;
int power;
int start, end, power;
Run(int start, int end, int power) {
this.start = start;
@ -24,27 +23,21 @@ public class ASort {
int n = array.length;
if (n < 2) return;
Stack<Run> runs = new Stack<>();
Deque<Run> runs = new ArrayDeque<>();
int i = 0;
while (i < n) {
// Find the next run
int j = extendRunRight(array, comparator, i, n);
// Compute the power of the run
int power = calculatePower(runs, i, j);
// Merge runs if needed based on power comparison
while (!runs.isEmpty() && power <= runs.peek().power) {
while (!runs.isEmpty() && power <= runs.peekLast().power) {
mergeRuns(array, comparator, runs);
}
// Push the current run
runs.push(new Run(i, j, power));
runs.addLast(new Run(i, j, power));
i = j;
}
// Merge remaining runs
while (runs.size() > 1) {
mergeRuns(array, comparator, runs);
}
@ -55,20 +48,16 @@ public class ASort {
if (runEnd == end) return runEnd;
// Check for ascending or descending order
if (comparator.compare(array[runEnd], array[start]) < 0) {
// Descending run
while (runEnd < end && comparator.compare(array[runEnd], array[runEnd - 1]) < 0) {
runEnd++;
}
reverseRange(array, start, runEnd);
} else {
// Ascending run
while (runEnd < end && comparator.compare(array[runEnd], array[runEnd - 1]) >= 0) {
runEnd++;
}
}
return runEnd;
}
@ -81,58 +70,56 @@ public class ASort {
}
}
private static int calculatePower(Stack<Run> runs, int currentStart, int currentEnd) {
if (runs.isEmpty()) {
return 0; // First run always has power 0
}
private static int calculatePower(Deque<Run> runs, int currentStart, int currentEnd) {
if (runs.isEmpty()) return 0;
Run topRun = runs.peek();
Run topRun = runs.peekLast();
int size1 = topRun.end - topRun.start;
int size2 = currentEnd - currentStart;
return Math.max(topRun.power, (int) (Math.log(size1 + size2) / Math.log(2))) + 1;
return Math.max(topRun.power, Integer.highestOneBit(size1 + size2)) + 1;
}
private static <T> void mergeRuns(T[] array, Comparator<? super T> comparator, Stack<Run> runs) {
while (runs.size() > 1) {
Run run2 = runs.pop();
Run run1 = runs.pop();
private static <T> void mergeRuns(T[] array, Comparator<? super T> comparator, Deque<Run> runs) {
if (runs.size() < 2) return;
// Merge runs and recalculate power
merge(array, comparator, run1.start, run1.end, run2.end);
int newPower = Math.max(run1.power, run2.power) + 1;
Run run2 = runs.removeLast();
Run run1 = runs.removeLast();
runs.push(new Run(run1.start, run2.end, newPower));
}
merge(array, comparator, run1.start, run1.end, run2.end);
int newPower = Math.max(run1.power, run2.power) + 1;
runs.addLast(new Run(run1.start, run2.end, newPower));
}
private static <T> void merge(T[] array, Comparator<? super T> comparator, int lo, int mid, int hi) {
T[] left = java.util.Arrays.copyOfRange(array, lo, mid);
List<T> merged = Arrays.stream(array, lo, mid)
.sorted(comparator)
.collect(Collectors.toList());
int i = 0, j = mid, k = lo;
while (i < left.length && j < hi) {
if (comparator.compare(left[i], array[j]) <= 0) {
array[k++] = left[i++];
} else {
array[k++] = array[j++];
}
while (i < merged.size() && j < hi) {
array[k++] = comparator.compare(merged.get(i), array[j]) <= 0 ? merged.get(i++) : array[j++];
}
while (i < left.length) {
array[k++] = left[i++];
while (i < merged.size()) {
array[k++] = merged.get(i++);
}
}
public static void main(String[] args) {
Integer[] array = {0, 1, 2, 3, 4, 5, -5, -4, -3, -2, -1, -10, -9, -8, -7, -6};
System.out.println("Before sorting:");
java.util.Arrays.stream(array).forEach(e -> System.out.print(e + " "));
Arrays.stream(array).forEach(e -> System.out.print(e + " "));
sort(array, Integer::compareTo);
System.out.println("\nAfter sorting:");
java.util.Arrays.stream(array).forEach(e -> System.out.print(e + " "));
Arrays.stream(array).forEach(e -> System.out.print(e + " "));
}
}