mirror of
https://gitlab.uni-marburg.de/langbeid/powersort.git
synced 2025-01-21 19:50:35 +01:00
Merge remote-tracking branch 'origin/implementation/Ambili'
This commit is contained in:
commit
09ee6a6e5f
129
app/src/main/java/de/uni_marburg/powersort/ASort.java
Normal file
129
app/src/main/java/de/uni_marburg/powersort/ASort.java
Normal file
@ -0,0 +1,129 @@
|
||||
package de.uni_marburg.powersort;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.Stack;
|
||||
|
||||
public class ASort {
|
||||
|
||||
private static class Run {
|
||||
int start, end;
|
||||
int power;
|
||||
|
||||
Run(int start, int end, int power) {
|
||||
this.start = start;
|
||||
this.end = end;
|
||||
this.power = power;
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> void sort(T[] array, Comparator<? super T> comparator) {
|
||||
if (array == null || comparator == null) {
|
||||
throw new IllegalArgumentException("Array and comparator must not be null");
|
||||
}
|
||||
|
||||
int n = array.length;
|
||||
if (n < 2) return;
|
||||
|
||||
Stack<Run> runs = new Stack<>();
|
||||
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.isEmpty() ? null : runs.peek(), i, j);
|
||||
|
||||
// Merge runs if needed based on power comparison
|
||||
while (!runs.isEmpty() && power <= runs.peek().power) {
|
||||
mergeRuns(array, comparator, runs);
|
||||
}
|
||||
|
||||
// Push the current run
|
||||
runs.push(new Run(i, j, power));
|
||||
i = j;
|
||||
}
|
||||
|
||||
// Merge remaining runs
|
||||
while (runs.size() > 1) {
|
||||
mergeRuns(array, comparator, runs);
|
||||
}
|
||||
}
|
||||
|
||||
private static <T> int extendRunRight(T[] array, Comparator<? super T> comparator, int start, int end) {
|
||||
int runEnd = start + 1;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
private static <T> void reverseRange(T[] array, int start, int end) {
|
||||
end--;
|
||||
while (start < end) {
|
||||
T temp = array[start];
|
||||
array[start++] = array[end];
|
||||
array[end--] = temp;
|
||||
}
|
||||
}
|
||||
|
||||
private static int calculatePower(Run previousRun, int currentStart, int currentEnd) {
|
||||
if (previousRun == null) {
|
||||
return 0; // First run
|
||||
}
|
||||
|
||||
int previousSize = previousRun.end - previousRun.start;
|
||||
int currentSize = currentEnd - currentStart;
|
||||
return (int) (Math.log(previousSize + currentSize) / Math.log(2));
|
||||
}
|
||||
|
||||
private static <T> void mergeRuns(T[] array, Comparator<? super T> comparator, Stack<Run> runs) {
|
||||
Run run2 = runs.pop();
|
||||
Run run1 = runs.pop();
|
||||
|
||||
merge(array, comparator, run1.start, run1.end, run2.end);
|
||||
runs.push(new Run(run1.start, run2.end, calculatePower(null, run1.start, run2.end)));
|
||||
}
|
||||
|
||||
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);
|
||||
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 < left.length) {
|
||||
array[k++] = left[i++];
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
Integer[] array = {5, 2, 9, 1, 5, 6, 3, 7, 4, 8};
|
||||
System.out.println("Before sorting:");
|
||||
java.util.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 + " "));
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user