Reusing "merge" method again and getting a little better results in IMPL_M_1

This commit is contained in:
M-H9 2025-01-16 09:59:27 +01:00
parent 42a0c24f67
commit e526c67c3c
3 changed files with 33 additions and 28 deletions

View File

@ -54,19 +54,34 @@ public class IMPL_M_1 {
} }
static <T> List<T> merge(List<T> run1, List<T> run2, Comparator<? super T> c) { static <T> T[] merge(T[] run1, T[] run2, Comparator<? super T> c) {
List<T> result = new ArrayList<>(); /**
while (!run1.isEmpty() && !run2.isEmpty()) { * We need this because:
* In Java, you cannot create generic arrays directly (can't write new T[size])
* The workaround is to create an Object array and cast it to T[]
* This casting generates a warning because the compiler can't verify the type safety at runtime due to Java's type erasure
* **/
@SuppressWarnings("unchecked")
T[] result = (T[]) new Object[run1.length + run2.length];
int i = 0, j = 0, k = 0;
while (i < run1.length && j < run2.length) {
//This comparison only works if the lists are sorted //This comparison only works if the lists are sorted
if (c.compare(run1.getFirst(),run2.getFirst()) < 0) { if (c.compare(run1[i], run2[j]) <= 0) {
result.add(run1.removeFirst()); result[k++] = run1[i++];
} else { } else {
result.add(run2.removeFirst()); result[k++] = run2[j++];
} }
} }
// can be improved by finding out which one is empty and only add the other one // can be improved by finding out which one is empty and only add the other one
result.addAll(run1); // Copy remaining elements
result.addAll(run2); while (i < run1.length) {
result[k++] = run1[i++];
}
while (j < run2.length) {
result[k++] = run2[j++];
}
return result; return result;
} }
@ -87,7 +102,7 @@ public class IMPL_M_1 {
static <T> void mergeInplace(T[] a, int i, int m, int j, Comparator<? super T> c) { static <T> void mergeInplace(T[] a, int i, int m, int j, Comparator<? super T> c) {
// System.out.printf("Merge(%d, %d, %d)%n", i, m, j); // System.out.printf("Merge(%d, %d, %d)%n", i, m, j);
MERGE_COST += j - i; MERGE_COST += j - i;
// Create temporary arrays for merging // Create temporary arrays for merging
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
T[] left = (T[]) new Object[m - i]; T[] left = (T[]) new Object[m - i];
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@ -98,22 +113,11 @@ public class IMPL_M_1 {
System.arraycopy(a, m, right, 0, j - m); System.arraycopy(a, m, right, 0, j - m);
// Merge back to original array // Merge back to original array
int k = i, l = 0, r = 0; // Merge the runs
while (l < left.length && r < right.length) { T[] merged = merge(left, right, c);
if (c.compare(left[l], right[r]) <= 0) {
a[k++] = left[l++];
} else {
a[k++] = right[r++];
}
}
// Copy remaining elements //copy back to original array
while (l < left.length) { System.arraycopy(merged, 0, a, i,merged.length);
a[k++] = left[l++];
}
while (r < right.length) {
a[k++] = right[r++];
}
} }

View File

@ -79,7 +79,7 @@ public class IMPL_M_2<T>{
* of the minimum stack length required as a function of the length * of the minimum stack length required as a function of the length
* of the array being sorted and the minimum merge sequence length. * of the array being sorted and the minimum merge sequence length.
*/ */
private static final int MIN_MERGE = 24; private static final int MIN_MERGE = 32;
/** /**
* The array being sorted. * The array being sorted.

View File

@ -6,6 +6,7 @@ import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.IntStream; import java.util.stream.IntStream;
import de.uni_marburg.powersort.benchmark.NaturalOrder;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import static de.uni_marburg.powersort.MSort.IMPL_M_1.MERGE_COST; import static de.uni_marburg.powersort.MSort.IMPL_M_1.MERGE_COST;
@ -34,11 +35,11 @@ class PowerSortTest {
@Test @Test
public void testWithFinnInputList() { public void testWithFinnInputList() {
List<Integer> numbers = List.of(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}); //T [] 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});
// powerSort(numbers); //powerSort(numbers, NaturalOrder.INSTANCE);
System.out.println("Result: "); System.out.println("Result: ");
System.out.println(new ArrayList<>(List.of(numbers))); // System.out.println(new ArrayList<>(List.of(numbers)));
} }
} }