diff --git a/app/src/main/java/de/uni_marburg/powersort/sort/ASort.java b/app/src/main/java/de/uni_marburg/powersort/sort/ASort.java index f93c57d..29579f0 100644 --- a/app/src/main/java/de/uni_marburg/powersort/sort/ASort.java +++ b/app/src/main/java/de/uni_marburg/powersort/sort/ASort.java @@ -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 runs = new Stack<>(); + Deque 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 runs, int currentStart, int currentEnd) { - if (runs.isEmpty()) { - return 0; // First run always has power 0 - } + private static int calculatePower(Deque 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 void mergeRuns(T[] array, Comparator comparator, Stack runs) { - while (runs.size() > 1) { - Run run2 = runs.pop(); - Run run1 = runs.pop(); + private static void mergeRuns(T[] array, Comparator comparator, Deque 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 void merge(T[] array, Comparator comparator, int lo, int mid, int hi) { - T[] left = java.util.Arrays.copyOfRange(array, lo, mid); + List 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 + " ")); } } + +