diff --git a/result.xls b/result.xls new file mode 100644 index 0000000..8a28047 Binary files /dev/null and b/result.xls differ diff --git a/src/ru/mail/polis/bench/AverageTimeBench.java b/src/ru/mail/polis/bench/AverageTimeBench.java index 0dc2b7d..ad9e004 100644 --- a/src/ru/mail/polis/bench/AverageTimeBench.java +++ b/src/ru/mail/polis/bench/AverageTimeBench.java @@ -19,8 +19,7 @@ import org.openjdk.jmh.runner.options.Options; import org.openjdk.jmh.runner.options.OptionsBuilder; -import ru.mail.polis.sort.BubbleSort; -import ru.mail.polis.sort.Helper; +import ru.mail.polis.sort.*; /** * Created by Nechaev Mikhail @@ -41,10 +40,9 @@ public class AverageTimeBench { @Setup(value = Level.Trial) public void setUpTrial() { - data = new int[10][100]; + data = new int[10][]; for (int i = 0; i < 10; i++) { - //define arrays here - data[i] = Helper.gen(100); + data[i] = Helper.genSortedDESC(1000); } } @@ -54,11 +52,51 @@ public void setUpInvocation() { index = (index + 1) % 10; } - @Benchmark + /*@Benchmark public void measureBubbleSort() { BubbleSort.sort(curr); } + @Benchmark + public void measureInsertionSort() { + InsertionSort.sort(curr); + } + + @Benchmark + public void measureImprovedInsertionSort() { + ImprovedInsertionSort.sort(curr); + } + + @Benchmark + public void measureShellSort() { + ShellSort.sort(curr); + }*/ + + @Benchmark + public void measureMergeSort() { + MergeSort.sort(curr); + } + + @Benchmark + public void measureMemoryOptimisedMergeSort() { + MemoryOptimisedMergeSort.sort(curr); + } + + @Benchmark + public void measureQuickSort() { + QuickSort.sort(curr); + } + + @Benchmark + public void measureRandomPivot3PartQuickSort() { + MemoryOptimisedMergeSort.sort(curr); + } + + @Benchmark + public void measureBinaryQuickSort() { + BinaryQuickSort.sort(curr); + } + public static void main(String[] args) throws RunnerException { Options opt = new OptionsBuilder() .include(AverageTimeBench.class.getSimpleName()) diff --git a/src/ru/mail/polis/bench/ImprovedInsertionSortBench.java b/src/ru/mail/polis/bench/ImprovedInsertionSortBench.java new file mode 100644 index 0000000..8c881ab --- /dev/null +++ b/src/ru/mail/polis/bench/ImprovedInsertionSortBench.java @@ -0,0 +1,49 @@ +package ru.mail.polis.bench; + +import java.util.concurrent.TimeUnit; + +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Level; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.infra.Blackhole; +import org.openjdk.jmh.runner.Runner; +import org.openjdk.jmh.runner.RunnerException; +import org.openjdk.jmh.runner.options.Options; +import org.openjdk.jmh.runner.options.OptionsBuilder; + +import ru.mail.polis.sort.ImprovedInsertionSort; +import ru.mail.polis.sort.Helper; + +@State(Scope.Thread) +@BenchmarkMode(Mode.AverageTime) +@OutputTimeUnit(TimeUnit.MICROSECONDS) +public class ImprovedInsertionSortBench { + + private int[] a; + + @Setup(value = Level.Invocation) + public void setUpInvocation() { + a = Helper.gen(1000); + } + + @Benchmark + public void measureImprovedInsertionSort(Blackhole bh) { + bh.consume(ImprovedInsertionSort.sort(a)); + } + + public static void main(String[] args) throws RunnerException { + Options opt = new OptionsBuilder() + .include(ImprovedInsertionSortBench.class.getSimpleName()) + .warmupIterations(5) + .measurementIterations(5) + .forks(1) + .build(); + + new Runner(opt).run(); + } +} diff --git a/src/ru/mail/polis/bench/InsertionSortBench.java b/src/ru/mail/polis/bench/InsertionSortBench.java new file mode 100644 index 0000000..c711732 --- /dev/null +++ b/src/ru/mail/polis/bench/InsertionSortBench.java @@ -0,0 +1,49 @@ +package ru.mail.polis.bench; + +import java.util.concurrent.TimeUnit; + +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Level; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.infra.Blackhole; +import org.openjdk.jmh.runner.Runner; +import org.openjdk.jmh.runner.RunnerException; +import org.openjdk.jmh.runner.options.Options; +import org.openjdk.jmh.runner.options.OptionsBuilder; + +import ru.mail.polis.sort.InsertionSort; +import ru.mail.polis.sort.Helper; + +@State(Scope.Thread) +@BenchmarkMode(Mode.AverageTime) +@OutputTimeUnit(TimeUnit.MICROSECONDS) +public class InsertionSortBench { + + private int[] a; + + @Setup(value = Level.Invocation) + public void setUpInvocation() { + a = Helper.gen(1000); + } + + @Benchmark + public void measureInsertionSort(Blackhole bh) { + bh.consume(InsertionSort.sort(a)); + } + + public static void main(String[] args) throws RunnerException { + Options opt = new OptionsBuilder() + .include(InsertionSortBench.class.getSimpleName()) + .warmupIterations(5) + .measurementIterations(5) + .forks(1) + .build(); + + new Runner(opt).run(); + } +} diff --git a/src/ru/mail/polis/sort/BinaryQuickSort.java b/src/ru/mail/polis/sort/BinaryQuickSort.java new file mode 100644 index 0000000..841a162 --- /dev/null +++ b/src/ru/mail/polis/sort/BinaryQuickSort.java @@ -0,0 +1,46 @@ +package ru.mail.polis.sort; + +public class BinaryQuickSort { + + private static final int INT_BINARY_LENGTH = 31; + + public static int[] sort(int[] a) { + if (a == null) + return new int[0]; + + if (a.length == 0 || a.length == 1) + return a; + + performSort(a, 0, a.length - 1, INT_BINARY_LENGTH); + + return a; + } + + public static int[] performSort(int[] arr, int l, int r, int bit){ + if (l < r && !(bit < 0)) { + int index = partition(arr, l, r, bit); + + performSort(arr, l, index, bit - 1); + performSort(arr, index + 1, r, bit - 1); + } + + return arr; + } + + static int getBit(int n, int k) { + return (n >> k) & 1; + } + + public static int partition(int[] a, int l, int r, int bit){ + int i = l; + int j = r; + + while (i <= j) { + while (i < a.length && getBit(a[i], bit) == 0) i++; + while (j > -1 && getBit(a[j], bit) == 1) j--; + if (i <= j) Helper.swap(a, i++, j--); + } + + return j; + } +} \ No newline at end of file diff --git a/src/ru/mail/polis/sort/BubbleSort.java b/src/ru/mail/polis/sort/BubbleSort.java index cb20691..b46bb79 100644 --- a/src/ru/mail/polis/sort/BubbleSort.java +++ b/src/ru/mail/polis/sort/BubbleSort.java @@ -3,6 +3,9 @@ public class BubbleSort { public static int[] sort(int a[]) { + if (a == null) + return new int[0]; + boolean wasSwap = true; int j = 0; while (wasSwap) { diff --git a/src/ru/mail/polis/sort/Helper.java b/src/ru/mail/polis/sort/Helper.java index aeb7a0c..5d707e2 100644 --- a/src/ru/mail/polis/sort/Helper.java +++ b/src/ru/mail/polis/sort/Helper.java @@ -1,6 +1,7 @@ package ru.mail.polis.sort; import java.util.Random; +import java.util.Arrays; import java.util.concurrent.ThreadLocalRandom; public class Helper { @@ -24,4 +25,91 @@ public static int[] gen(int n) { } return a; } + + public static int[] genSortedASC(int n) { + int[] a = Helper.gen(n); + Arrays.sort(a); + return a; + } + + public static int[] genSortedDESC(int n) { + int[] a = Helper.genSortedASC(n); + + for (int i = 0; i < a.length / 2; i++) { + Helper.swap(a, i, a.length - i - 1); + } + + return a; + } + + public static int[] genWorstCaseForMergeSort(int n) { + int[] a = Helper.genSortedASC(n); + Helper.worseCaseForMergeSortSeparate(a); + return a; + } + + public static void worseCaseForMergeSortSeparate(int[] a) { + if(a.length <= 1) + return; + + if(a.length == 2) + { + int swap = a[0]; + a[0] = a[1]; + a[1] = swap; + return; + } + + int i, j; + int m = (a.length + 1) / 2; + int left[] = new int[m]; + int right[] = new int[a.length - m]; + + for(i = 0, j = 0 ;i < a.length; i = i + 2, j++) + left[j]=a[i]; + + for(i = 1, j = 0; i < a.length; i = i + 2, j++) + right[j] = a[i]; + + Helper.worseCaseForMergeSortSeparate(left); + Helper.worseCaseForMergeSortSeparate(right); + Helper.worseCaseForMergeSortMerge(a, left, right); + } + + public static void worseCaseForMergeSortMerge(int[] a, int[] left, int[] right) { + int i, j; + for(i = 0; i < left.length; i++) { + a[i] = left[i]; + } + for(j = 0; j < right.length; j++, i++) { + a[i] = right[j]; + } + } + + public static int[] genWorstCaseForQuickSort(int n){ + int[] a = Helper.genSortedASC(n); + worstCaseForQuickSort(a); + return a; + } + + public static void worstCaseForQuickSort(int[] a) + { + for (int i = 2; i < a.length;i++) + swap(a, i, i / 2); + } + + public static int binarySearch(int[] a, int key, int right) { + int left = -1; + int mid; + while (left < right - 1) { + mid = left + (right - left) / 2; + + if (a[mid] < key) { + left = mid; + } else { + right = mid; + } + } + return right; + } } diff --git a/src/ru/mail/polis/sort/ImprovedInsertionSort.java b/src/ru/mail/polis/sort/ImprovedInsertionSort.java new file mode 100644 index 0000000..076cf75 --- /dev/null +++ b/src/ru/mail/polis/sort/ImprovedInsertionSort.java @@ -0,0 +1,17 @@ +package ru.mail.polis.sort; + +public class ImprovedInsertionSort { + + public static int[] sort(int a[]) { + if (a == null) + return new int[0]; + + for(int i = 0; i < a.length - 1; i++){ + int p = Helper.binarySearch(a, a[i], i); + int aP = a[i]; + System.arraycopy(a, p, a, p + 1, i - p); + a[p] = aP; + } + return a; + } +} diff --git a/src/ru/mail/polis/sort/InsertionSort.java b/src/ru/mail/polis/sort/InsertionSort.java new file mode 100644 index 0000000..b07d1dc --- /dev/null +++ b/src/ru/mail/polis/sort/InsertionSort.java @@ -0,0 +1,24 @@ +package ru.mail.polis.sort; + +public class InsertionSort { + /*public static void main(String[] args) { + int [] a = {5, 6, 1, 7, 9}; + + InsertionSort.sort(a); + for(int i = 0; i < a.length; i++){ + System.out.print(a[i] + " "); + } + }*/ + + public static int[] sort(int a[]) { + if (a == null) + return new int[0]; + + for(int i = 0; i < a.length; i++){ + for(int j = i; j > 0 && a[j] < a[j - 1]; j--){ + Helper.swap(a, j, j - 1); + } + } + return a; + } +} diff --git a/src/ru/mail/polis/sort/MemoryOptimisedMergeSort.java b/src/ru/mail/polis/sort/MemoryOptimisedMergeSort.java new file mode 100644 index 0000000..98eec5c --- /dev/null +++ b/src/ru/mail/polis/sort/MemoryOptimisedMergeSort.java @@ -0,0 +1,46 @@ +package ru.mail.polis.sort; + + +public class MemoryOptimisedMergeSort { + public static int[] sort(int[] a){ + if (a == null) + return new int[0]; + if (a.length == 0 || a.length == 1) + return a; + + return performSort(a, 0, a.length - 1); + } + + static int[] performSort(int[] a, int min, int max){ + if(max - min == 1){ + if(a[min] > a[max]) { + Helper.swap(a, min, max); + } + } else if(max - min != 0) { + int mid = ( (int) Math.floor(min + (max - min) / 2)); + + performSort(a, min, mid); + performSort(a, mid + 1, max); + mergeArrays(a, min, max, mid); + } + return a; + } + + static void mergeArrays(int[] a, int min, int max, int mid){ + int i = min; + while(i <= mid){ + if(a[i] > a[mid + 1]){ + Helper.swap(a, i, mid + 1); + push(a, mid + 1, max); + } + i++; + } + } + + static void push(int[] aForPush, int s, int e){ + for(int i = s; i < e; i++){ + if(aForPush[i] > aForPush[i + 1]) + Helper.swap(aForPush, i , i + 1); + } + } +} diff --git a/src/ru/mail/polis/sort/MergeSort.java b/src/ru/mail/polis/sort/MergeSort.java new file mode 100644 index 0000000..e13f0a9 --- /dev/null +++ b/src/ru/mail/polis/sort/MergeSort.java @@ -0,0 +1,40 @@ +package ru.mail.polis.sort; + +import java.util.Arrays; + +public class MergeSort { + public static int[] sort(int a[]) { + if (a == null) + return new int[0]; + + if (a.length == 0 || a.length == 1) { + return a; + } + + int avg = a.length / 2; + int[] leftPart = Arrays.copyOf(a, avg); + int[] rightPart = Arrays.copyOfRange(a, avg, a.length); + + leftPart = sort(leftPart); + rightPart = sort(rightPart); + + int i = 0, j = 0; + while (i < leftPart.length && j < rightPart.length) { + if (leftPart[i] <= rightPart[j]) { + a[i + j] = leftPart[i++]; + } else { + a[i + j] = rightPart[j++]; + } + } + + while (i < leftPart.length) { + a[i + j] = leftPart[i++]; + } + + while (j < rightPart.length) { + a[i + j] = rightPart[j++]; + } + + return a; + } +} diff --git a/src/ru/mail/polis/sort/QuickSort.java b/src/ru/mail/polis/sort/QuickSort.java new file mode 100644 index 0000000..a150acb --- /dev/null +++ b/src/ru/mail/polis/sort/QuickSort.java @@ -0,0 +1,43 @@ +package ru.mail.polis.sort; + +public class QuickSort { + + public static int[] sort(int[] a) { + if (a == null) + return new int[0]; + + if (a.length == 0 || a.length == 1) + return a; + + performSort(a, 0, a.length - 1); + + return a; + } + + private static void performSort(int[] a, int low, int high) { + int i = low, j = high; + + int pivot = a[low + (high - low) / 2]; + + while (i <= j) { + while (a[i] < pivot) { + i++; + } + + while (a[j] > pivot) { + j--; + } + + if (i <= j) { + Helper.swap(a, i, j); + i++; + j--; + } + } + //recur + if (low < j) + performSort(a,low, j); + if (i < high) + performSort(a, i, high); + } +} diff --git a/src/ru/mail/polis/sort/RandomPivot3PartQuickSort.java b/src/ru/mail/polis/sort/RandomPivot3PartQuickSort.java new file mode 100644 index 0000000..988134f --- /dev/null +++ b/src/ru/mail/polis/sort/RandomPivot3PartQuickSort.java @@ -0,0 +1,51 @@ +package ru.mail.polis.sort; + +import java.util.Random; + +public class RandomPivot3PartQuickSort { + + public static int[] sort(int[] a) { + if (a == null) + return new int[0]; + + performSort(a, 0, a.length - 1); + return a; + } + + private static void performSort(int a[], int left, int right) { + if (left >= right) { + return; + } + + Random r = new Random(); + + int index = r.nextInt(right - left + 1) + left; + + Helper.swap(a, left, index); + + int x = a[left]; + int j = left; + int k = left; + + for (int i = left + 1; i <= right; i++) { + if (a[i] < x) { + j++; + Helper.swap(a, i , j); + } else if (a[i] == x) { + k++; + j++; + Helper.swap(a, i, j); + Helper.swap(a, k, j); + } + } + + int temp = j; + + for (int i = left; i <= k; i++) { + Helper.swap(a, i, j--); + } + + performSort(a, left, j); + performSort(a, temp + 1, right); + } +} \ No newline at end of file diff --git a/src/ru/mail/polis/sort/ShellSort.java b/src/ru/mail/polis/sort/ShellSort.java new file mode 100644 index 0000000..d6f0d3b --- /dev/null +++ b/src/ru/mail/polis/sort/ShellSort.java @@ -0,0 +1,31 @@ +package ru.mail.polis.sort; + +public class ShellSort { + + public static int[] sort(int a[]) { + if (a == null) + return new int[0]; + + int inner, outer; + int temp; + + int h = 1; + while (h <= a.length / 3) { + h = h * 3 + 1; + } + while (h > 0) { + for (outer = h; outer < a.length; outer++) { + temp = a[outer]; + inner = outer; + + while (inner > h - 1 && a[inner - h] >= temp) { + a[inner] = a[inner - h]; + inner -= h; + } + a[inner] = temp; + } + h = (h - 1) / 3; + } + return a; + } +} diff --git a/tests/ru/mail/polis/sort/valid/Tester.java b/tests/ru/mail/polis/sort/valid/Tester.java index 01d1b2f..96dce62 100644 --- a/tests/ru/mail/polis/sort/valid/Tester.java +++ b/tests/ru/mail/polis/sort/valid/Tester.java @@ -16,6 +16,14 @@ import org.junit.runners.Parameterized; import ru.mail.polis.sort.BubbleSort; +import ru.mail.polis.sort.InsertionSort; +import ru.mail.polis.sort.ImprovedInsertionSort; +import ru.mail.polis.sort.ShellSort; +import ru.mail.polis.sort.MergeSort; +import ru.mail.polis.sort.MemoryOptimisedMergeSort; +import ru.mail.polis.sort.QuickSort; +import ru.mail.polis.sort.RandomPivot3PartQuickSort; +import ru.mail.polis.sort.BinaryQuickSort; import ru.mail.polis.sort.Helper; @RunWith(value = Parameterized.class) @@ -34,6 +42,8 @@ protected void starting(final Description description) { @Parameterized.Parameters(name = "{index}") public static Collection data() { return Arrays.asList(new int[][]{ + null, + {}, {0}, {0, 0, 0, 0}, {4, 3, 2, 1}, @@ -61,4 +71,38 @@ public void test01_checkBubbleSort() throws IOException { Assert.assertTrue(isSorted(BubbleSort.sort(array))); } + @Test + public void test02_checkInsertionSort() throws IOException { + Assert.assertTrue(isSorted(InsertionSort.sort(array))); + } + + @Test + public void test03_checkImprovedInsertionSort() throws IOException { + Assert.assertTrue(isSorted(ImprovedInsertionSort.sort(array))); + } + + @Test + public void test04_checkShellSort() throws IOException { + Assert.assertTrue(isSorted(ShellSort.sort(array))); + } + + @Test + public void test05_checkMergeSort() throws IOException { + Assert.assertTrue(isSorted(MergeSort.sort(array))); + } + + @Test + public void test06_checkMemoryOptimisedMergeSort() throws IOException { + Assert.assertTrue(isSorted(MemoryOptimisedMergeSort.sort(array))); + } + + @Test + public void test07_checkQuickSort() throws IOException { + Assert.assertTrue(isSorted(QuickSort.sort(array))); + } + + @Test + public void test08_checkRandomPivot3PartQuickSort() throws IOException { + Assert.assertTrue(isSorted(RandomPivot3PartQuickSort.sort(array))); + } }