mirror of
https://gitlab.uni-marburg.de/langbeid/powersort.git
synced 2025-04-02 07:36:03 +02:00
refactor
This commit is contained in:
parent
691d7eb0ac
commit
89c0ca10c7
@ -1,13 +1,12 @@
|
|||||||
package de.uni_marburg.powersort.sort;
|
package de.uni_marburg.powersort.sort;
|
||||||
|
|
||||||
import java.util.Comparator;
|
import java.util.*;
|
||||||
import java.util.Stack;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class ASort {
|
public class ASort {
|
||||||
|
|
||||||
private static class Run {
|
private static class Run {
|
||||||
int start, end;
|
int start, end, power;
|
||||||
int power;
|
|
||||||
|
|
||||||
Run(int start, int end, int power) {
|
Run(int start, int end, int power) {
|
||||||
this.start = start;
|
this.start = start;
|
||||||
@ -24,27 +23,21 @@ public class ASort {
|
|||||||
int n = array.length;
|
int n = array.length;
|
||||||
if (n < 2) return;
|
if (n < 2) return;
|
||||||
|
|
||||||
Stack<Run> runs = new Stack<>();
|
Deque<Run> runs = new ArrayDeque<>();
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
while (i < n) {
|
while (i < n) {
|
||||||
// Find the next run
|
|
||||||
int j = extendRunRight(array, comparator, i, n);
|
int j = extendRunRight(array, comparator, i, n);
|
||||||
|
|
||||||
// Compute the power of the run
|
|
||||||
int power = calculatePower(runs, i, j);
|
int power = calculatePower(runs, i, j);
|
||||||
|
|
||||||
// Merge runs if needed based on power comparison
|
while (!runs.isEmpty() && power <= runs.peekLast().power) {
|
||||||
while (!runs.isEmpty() && power <= runs.peek().power) {
|
|
||||||
mergeRuns(array, comparator, runs);
|
mergeRuns(array, comparator, runs);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Push the current run
|
runs.addLast(new Run(i, j, power));
|
||||||
runs.push(new Run(i, j, power));
|
|
||||||
i = j;
|
i = j;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Merge remaining runs
|
|
||||||
while (runs.size() > 1) {
|
while (runs.size() > 1) {
|
||||||
mergeRuns(array, comparator, runs);
|
mergeRuns(array, comparator, runs);
|
||||||
}
|
}
|
||||||
@ -55,20 +48,16 @@ public class ASort {
|
|||||||
|
|
||||||
if (runEnd == end) return runEnd;
|
if (runEnd == end) return runEnd;
|
||||||
|
|
||||||
// Check for ascending or descending order
|
|
||||||
if (comparator.compare(array[runEnd], array[start]) < 0) {
|
if (comparator.compare(array[runEnd], array[start]) < 0) {
|
||||||
// Descending run
|
|
||||||
while (runEnd < end && comparator.compare(array[runEnd], array[runEnd - 1]) < 0) {
|
while (runEnd < end && comparator.compare(array[runEnd], array[runEnd - 1]) < 0) {
|
||||||
runEnd++;
|
runEnd++;
|
||||||
}
|
}
|
||||||
reverseRange(array, start, runEnd);
|
reverseRange(array, start, runEnd);
|
||||||
} else {
|
} else {
|
||||||
// Ascending run
|
|
||||||
while (runEnd < end && comparator.compare(array[runEnd], array[runEnd - 1]) >= 0) {
|
while (runEnd < end && comparator.compare(array[runEnd], array[runEnd - 1]) >= 0) {
|
||||||
runEnd++;
|
runEnd++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return runEnd;
|
return runEnd;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,58 +70,56 @@ public class ASort {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int calculatePower(Stack<Run> runs, int currentStart, int currentEnd) {
|
private static int calculatePower(Deque<Run> runs, int currentStart, int currentEnd) {
|
||||||
if (runs.isEmpty()) {
|
if (runs.isEmpty()) return 0;
|
||||||
return 0; // First run always has power 0
|
|
||||||
}
|
|
||||||
|
|
||||||
Run topRun = runs.peek();
|
Run topRun = runs.peekLast();
|
||||||
int size1 = topRun.end - topRun.start;
|
int size1 = topRun.end - topRun.start;
|
||||||
int size2 = currentEnd - currentStart;
|
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) {
|
private static <T> void mergeRuns(T[] array, Comparator<? super T> comparator, Deque<Run> runs) {
|
||||||
while (runs.size() > 1) {
|
if (runs.size() < 2) return;
|
||||||
Run run2 = runs.pop();
|
|
||||||
Run run1 = runs.pop();
|
|
||||||
|
|
||||||
// Merge runs and recalculate power
|
Run run2 = runs.removeLast();
|
||||||
merge(array, comparator, run1.start, run1.end, run2.end);
|
Run run1 = runs.removeLast();
|
||||||
int newPower = Math.max(run1.power, run2.power) + 1;
|
|
||||||
|
|
||||||
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) {
|
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;
|
int i = 0, j = mid, k = lo;
|
||||||
|
|
||||||
while (i < left.length && j < hi) {
|
while (i < merged.size() && j < hi) {
|
||||||
if (comparator.compare(left[i], array[j]) <= 0) {
|
array[k++] = comparator.compare(merged.get(i), array[j]) <= 0 ? merged.get(i++) : array[j++];
|
||||||
array[k++] = left[i++];
|
|
||||||
} else {
|
|
||||||
array[k++] = array[j++];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while (i < left.length) {
|
while (i < merged.size()) {
|
||||||
array[k++] = left[i++];
|
array[k++] = merged.get(i++);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
Integer[] array = {0, 1, 2, 3, 4, 5, -5, -4, -3, -2, -1, -10, -9, -8, -7, -6};
|
Integer[] array = {0, 1, 2, 3, 4, 5, -5, -4, -3, -2, -1, -10, -9, -8, -7, -6};
|
||||||
System.out.println("Before sorting:");
|
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);
|
sort(array, Integer::compareTo);
|
||||||
|
|
||||||
System.out.println("\nAfter sorting:");
|
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 + " "));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user