From cac5af049f43252480e725762be9183b825cc14e Mon Sep 17 00:00:00 2001 From: norangebit Date: Sun, 9 Jun 2019 12:40:01 +0200 Subject: [PATCH] add sorting algorithms - edit mergesort - add quicksort - add countingsort --- .../algorithms/sorting/Countingsort.kt | 51 +++++++++++++ .../norangeb/algorithms/sorting/Mergesort.kt | 29 ++++---- .../norangeb/algorithms/sorting/Quicksort.kt | 74 +++++++++++++++++++ .../algorithms/sorting/CountingsortTest.kt | 43 +++++++++++ .../algorithms/sorting/QuicksortTest.kt | 64 ++++++++++++++++ 5 files changed, 247 insertions(+), 14 deletions(-) create mode 100644 src/main/kotlin/it/norangeb/algorithms/sorting/Countingsort.kt create mode 100644 src/main/kotlin/it/norangeb/algorithms/sorting/Quicksort.kt create mode 100644 src/test/kotlin/it/norangeb/algorithms/sorting/CountingsortTest.kt create mode 100644 src/test/kotlin/it/norangeb/algorithms/sorting/QuicksortTest.kt diff --git a/src/main/kotlin/it/norangeb/algorithms/sorting/Countingsort.kt b/src/main/kotlin/it/norangeb/algorithms/sorting/Countingsort.kt new file mode 100644 index 0000000..ca22078 --- /dev/null +++ b/src/main/kotlin/it/norangeb/algorithms/sorting/Countingsort.kt @@ -0,0 +1,51 @@ +/* + * MIT License + * + * Copyright (c) 2019 norangebit + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + */ + +package it.norangeb.algorithms.sorting + +object Countingsort { + + fun sort(array: Array, from: Int, to: Int) { + if (from >= to) + return + + val range = to - from + 1 + + val bucket = Array(range) { 0 } + + array.forEach { bucket[it - from] += 1 } + + bucket.forEachIndexed { index, i -> + if (index != 0) { + bucket[index] += bucket[index - 1] + } + } + val aux = array.clone() + + aux.forEach { + array[--bucket[it - from]] = it + } + } +} \ No newline at end of file diff --git a/src/main/kotlin/it/norangeb/algorithms/sorting/Mergesort.kt b/src/main/kotlin/it/norangeb/algorithms/sorting/Mergesort.kt index 589cab1..6ea8e45 100644 --- a/src/main/kotlin/it/norangeb/algorithms/sorting/Mergesort.kt +++ b/src/main/kotlin/it/norangeb/algorithms/sorting/Mergesort.kt @@ -27,13 +27,13 @@ package it.norangeb.algorithms.sorting object Mergesort : Sorter() { override fun sort(array: Array, isLess: (T, T) -> Boolean) { - val auxiliary = arrayOfNulls(array.size) as Array - sort(array, auxiliary, 0, array.size - 1, isLess) + val aux = array.clone() + sort(array, aux, 0, array.size - 1, isLess) } private fun sort( array: Array, - auxiliary: Array, + aux: Array, low: Int, high: Int, isLess: (T, T) -> Boolean @@ -42,35 +42,36 @@ object Mergesort : Sorter() { val mid = low + (high - low) / 2 - sort(array, auxiliary, low, mid, isLess) - sort(array, auxiliary, mid + 1, high, isLess) + sort(array, aux, low, mid, isLess) + sort(array, aux, mid + 1, high, isLess) - if (!isLess(array[mid+1], array[mid])) + if (isLess(array[mid], array[mid + 1])) return - merge(array, auxiliary, low, mid, high, isLess) + merge(array, aux, low, mid, high, isLess) } - private inline fun merge( + private fun merge( array: Array, - auxiliary: Array, + aux: Array, low: Int, mid: Int, high: Int, isLess: (T, T) -> Boolean ) { + for (i in low..high) - auxiliary[i] = array[i] + aux[i] = array[i] var i = low var j = mid + 1 for (k in low..high) when { - i > mid -> array[k] = auxiliary[j++] - j > high -> array[k] = auxiliary[i++] - isLess(auxiliary[j], auxiliary[i]) -> array[k] = auxiliary[j++] - else -> array[k] = auxiliary[i++] + i > mid -> array[k] = aux[j++] + j > high -> array[k] = aux[i++] + isLess(aux[i], aux[j]) -> array[k] = aux[i++] + else -> array[k] = aux[j++] } } } \ No newline at end of file diff --git a/src/main/kotlin/it/norangeb/algorithms/sorting/Quicksort.kt b/src/main/kotlin/it/norangeb/algorithms/sorting/Quicksort.kt new file mode 100644 index 0000000..c43b8cb --- /dev/null +++ b/src/main/kotlin/it/norangeb/algorithms/sorting/Quicksort.kt @@ -0,0 +1,74 @@ +/* + * MIT License + * + * Copyright (c) 2019 norangebit + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + */ + +package it.norangeb.algorithms.sorting + +object Quicksort : Sorter() { + override fun sort(array: Array, isLess: (T, T) -> Boolean) { + sort(array, 0, array.size - 1, isLess) + } + + private fun sort(array: Array, low: Int, high: Int, isLess: (T, T) -> Boolean) { + if (low >= high) + return + + val mid = partitioning(array, low, high, isLess) + + sort(array, low, mid - 1, isLess) + sort(array, mid + 1, high, isLess) + } + + private fun partitioning( + array: Array, + low: Int, + high: Int, + isLess: (T, T) -> Boolean + ): Int { + var i = low + var j = high + 1 + + while (true) { + while (isLess(array[++i], array[low])) + if (i == high) break + + while (isLess(array[low], array[--j])) + if (j == low) break + + if (i >= j) break + + swap(array, i, j) + } + + swap(array, low, j) + + return j + } + + private fun swap(array: Array, i: Int, j: Int) { + val tmp = array[i] + array[i] = array[j] + array[j] = tmp + } +} \ No newline at end of file diff --git a/src/test/kotlin/it/norangeb/algorithms/sorting/CountingsortTest.kt b/src/test/kotlin/it/norangeb/algorithms/sorting/CountingsortTest.kt new file mode 100644 index 0000000..b7b5761 --- /dev/null +++ b/src/test/kotlin/it/norangeb/algorithms/sorting/CountingsortTest.kt @@ -0,0 +1,43 @@ +/* + * MIT License + * + * Copyright (c) 2019 norangebit + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + */ + +package it.norangeb.algorithms.sorting + +import org.amshove.kluent.`should equal` +import org.junit.jupiter.api.Test + +class CountingsortTest { + + @Test + fun testSort() { + val array = arrayOf(13, 15, 11, 4, 5, 3, 2, 7, 1, 2, 3, 3, 6, 9, 11) + val arrayCopy = array.clone() + + Countingsort.sort(array, 1, 15) + + array `should equal` arrayCopy.sortedArray() + } +} + diff --git a/src/test/kotlin/it/norangeb/algorithms/sorting/QuicksortTest.kt b/src/test/kotlin/it/norangeb/algorithms/sorting/QuicksortTest.kt new file mode 100644 index 0000000..264bd55 --- /dev/null +++ b/src/test/kotlin/it/norangeb/algorithms/sorting/QuicksortTest.kt @@ -0,0 +1,64 @@ +/* + * MIT License + * + * Copyright (c) 2019 norangebit + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + */ + +package it.norangeb.algorithms.sorting + +import org.amshove.kluent.`should equal` +import org.junit.jupiter.api.Test + +class QuicksortTest { + + @Test + fun testSort() { + val array = arrayOf(5, 2, 3, 1, 4) + val arrayCopy = array.clone() + + Quicksort.sort(array) + + array `should equal` arrayCopy.sortedArray() + } + + @Test + fun testSortBy() { + val array = arrayOf(5, 2, 1, 4, 3, 23, 12, 1, 89, 7) + val arrayCopy = array.clone() + + Quicksort.sortBy(array) { it } + + array `should equal` arrayCopy.sortedArray() + } + + @Test + fun testSortWith() { + val array = arrayOf(4, 5, 3, 2, 1) + val arrayCopy = array.clone() + + Quicksort.sortWith(array) { t1, t2 -> + t1.compareTo(t2) + } + + array `should equal` arrayCopy.sortedArray() + } +} \ No newline at end of file