package ch.fhnw.claudemartin.algd2; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; import java.util.Collections; import java.util.LinkedList; import java.util.List; import java.util.ListIterator; import java.util.Random; import org.junit.Test; public class MSListTest extends MSList { private static final long serialVersionUID = 1L; @Test public void testMSList() throws Exception { Random rnd = new Random(123L); MSList list = new MSList<>(); for (int i = 0; i <= 100; i++) list.add((int) (rnd.nextInt(101))); MSList clone = list.clone(); assertEquals(list, clone); list.mergeSort(); Collections.sort(clone); assertEquals(clone, list); } @Test public void testGetIteratorAt() { MSList list = new MSList(); ListIterator itr = list.getIteratorAt(-1); assertEquals(0, itr.nextIndex()); assertEquals(-1, itr.previousIndex()); for (int i = 10; i > 0; i--) list.add(i); itr = list.getIteratorAt(5); assertSame(itr, list.getIteratorAt(5)); assertEquals(6, itr.nextIndex()); assertEquals(5, itr.previousIndex()); } @Test public void testMergeSortIntInt() { MSList list = new MSList(); for (int i = 10; i > 0; i--) list.add(i); MSList clone = list.clone(); int last = list.size() - 1; list.mergeSort(1, last - 1); assertEquals(list.get(0), clone.get(0)); assertEquals(list.get(1), clone.get(last - 1)); assertEquals(list.get(2), clone.get(last - 2)); // usw... assertEquals(list.get(last), clone.get(last)); } @Test public void testMerge() { { // Ganze Liste mergen: MSList list = new MSList(); for (int i = 0; i < 20; i++) { list.add(i); final int lastIdx = list.size() - 1; list.merge(0, lastIdx / 2, lastIdx); assertTrue(list.toString(), isSorted(list)); } list.addAll(list.clone()); final int lastIdx = list.size() - 1; list.merge(0, (lastIdx - 1) / 2, lastIdx); assertTrue(list.toString(), isSorted(list)); } {// Teilweise mergen: MSList list = new MSList(); for (int i = 0; i < 20; i++) list.add(i); // list ist bereits sortiert. Merge darf nichts ändern. for (int i = 0; i < list.size() / 2; i++) { MSList clone = list.clone(); final int left = i; final int right = list.size() - 1; list.merge(left, (left + right) / 2, right); assertEquals(clone, list); } } } @Test public void testSplit() { MSList list0 = new MSList(); for (int i = 0; i < 20; i++) list0.add(i); MSList list1 = list0.clone(); for (int i = 100; i < 20; i++) list0.add(i); MSList union = list0.clone(); union.addAll(list1); MSList[] split = union.split(); assertEquals(list0, split[0]); assertEquals(list1, split[1]); // Anzahl variierend: list0.clear(); for (int i = 0; i < 20; i++) { split = list0.split(); list1.clear(); list1.addAll(split[0]); list1.addAll(split[1]); assertEquals(list0, list1); list0.add(i); } } @Test public void testPerformance() { LinkedList readings = new LinkedList<>(); for (int n = 5000; n <= 80000; n*=2) { MSList list = new MSList(); for (int i = 0; i < n; i++) list.add(i % 17); MSList clone = list.clone(); long start = System.currentTimeMillis(); list.mergeSort(); long timeMS = System.currentTimeMillis() - start; System.out.println("MSList: " + timeMS); start = System.currentTimeMillis(); Collections.sort(clone); long timeJava = System.currentTimeMillis() - start; System.out.println("Java: " + timeJava); if (timeJava > 0 && timeJava < timeMS) { double reading = (timeMS / timeJava); System.out.println("MSList is " + reading + " times slower than Java with n="+n); readings.add(reading); } } double avg = 0d; for (Double r : readings) avg += r; avg /= readings.size(); System.out.println("Average: "+avg); } public static > boolean isSorted(List list) { T previous = null; for (T t : list) { if (previous != null && t.compareTo(previous) < 0) return false; previous = t; } return true; } }