diff --git a/.idea/gradle.xml b/.idea/gradle.xml index 6e368da..4979975 100644 --- a/.idea/gradle.xml +++ b/.idea/gradle.xml @@ -5,7 +5,6 @@ - + \ No newline at end of file diff --git a/app/src/main/java/de/uni_marburg/powersort/FinnSort/FinnSort.java b/app/src/main/java/de/uni_marburg/powersort/FinnSort/FinnSort.java new file mode 100644 index 0000000..bd84f69 --- /dev/null +++ b/app/src/main/java/de/uni_marburg/powersort/FinnSort/FinnSort.java @@ -0,0 +1,112 @@ +package de.uni_marburg.powersort.FinnSort; +import java.util.*; + +import static java.lang.Math.*; + +public class FinnSort { + + private static final ArrayList runs = new ArrayList<>(); + + static void sort(Integer[] a) { + + int n = a.length; + int i = 0; + int j = extendRunRight(a, i); + + printList(a); + + runs.add(new Run(i, j, 0)); + + i = j; + while (i < n) { + j = extendRunRight(a, i); + + //printRuns(); + + int p = power(runs.getLast(), new Run(i, j, 0), n); + + while (runs.size() >= 2 && p < power(runs.getLast(), runs.get(runs.size() - 2), n)) { + basicMerge(a, runs.removeFirst(), runs.removeFirst()); + } + + runs.add(new Run(i, j, p)); + i = j; + } + while (runs.size() >= 2) { + basicMerge(a, runs.removeFirst(), runs.removeFirst()); + } + } + + private static void basicMerge(Integer[] a, Run r1, Run r2) { + ArrayList run1 = new ArrayList<>(Arrays.asList(a).subList(r1.start, r1.end)); + ArrayList run2 = new ArrayList<>(Arrays.asList(a).subList(r2.start, r2.end)); + ArrayList merge = new ArrayList<>(); + + while (!run1.isEmpty() || !run2.isEmpty()) { + if (run2.isEmpty() || !run1.isEmpty() && run1.getFirst() < run2.getFirst()) { + merge.add(run1.removeFirst()); + } else { + merge.add(run2.removeFirst()); + } + } + + System.arraycopy(merge.toArray(), 0, a, min(r1.start, r2.start), merge.size()); + Run r = new Run(min(r1.start, r2.start), max(r1.end, r2.end), min(r1.power, r2.power)); + runs.add(r); + printList(a); + } + + private static int extendRunRight(Integer[] a, int i) { + int j = i + 1; + while (j < a.length && a[j-1] <= a[j]) { + j++; + } + return j; + } + + private static int power(Run run1, Run run2, int n) { + if (run1.start == 0) { + return 0; + } + int n_1 = run1.end - run1.start; + int n_2 = run2.end - run2.start; + double a = ((double) run1.start + 0.5 * n_1 - 1) / n; + double b = ((double) run2.start + 0.5 * n_2 - 1) / n; + int l = 0; + while ((int) (a * pow(2, l)) == (int) (b * pow(2 ,l))) { + l++; + } + return l; + } + + public static void printRuns() { + String s = ""; + for (Run run : runs) { + s += "(" + run.start + " - " + run.end + ", p: " + run.power + ") "; + } + System.out.println(s); + } + public static void printList(Integer[] arr) { + String s = ""; + int i = 0; + while (i < arr.length) { + String run = "["; + int j = extendRunRight(arr, i); + for (int t = i; t < j; t++) { + run += arr[t] + ", "; + } + s += run.substring(0, run.length()-2) +"]"; + i = j; + } + System.out.println(s); + } + + public static void main(String[] args) { + Integer[] numbers = new Integer[]{24, 25, 26, 27, 28, 21, 22, 23, 18, 19, 20, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 3, 1, 2}; + + + sort(numbers); + System.out.println("Result: "); + System.out.println(new ArrayList<>(List.of(numbers))); + } +} \ No newline at end of file diff --git a/app/src/main/java/de/uni_marburg/powersort/FinnSort/Run.java b/app/src/main/java/de/uni_marburg/powersort/FinnSort/Run.java new file mode 100644 index 0000000..eba6fc6 --- /dev/null +++ b/app/src/main/java/de/uni_marburg/powersort/FinnSort/Run.java @@ -0,0 +1,14 @@ +package de.uni_marburg.powersort.FinnSort; + +class Run { + int start; + int end; + int power; + + public Run(int i, int j, int p) { + start = i; + end = j; + power = p; + } + +}