added a new sorting algorithm Tim sort, added comments for MergeSort.kt file, edited some old comments

This commit is contained in:
evitwilly
2022-08-26 14:18:29 +03:00
parent 9fb45971f2
commit 37257596b0
13 changed files with 204 additions and 32 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+1
View File
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GradleMigrationSettings" migrationVersion="1" />
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
-7
View File
@@ -1,7 +0,0 @@
import sorting.mergeSort
fun main() {
val array = arrayOf(5, 4, 3, 2, 1, 0)
array.mergeSort()
print(array.toList())
}
+11
View File
@@ -1,5 +1,16 @@
package sorting
/**
* merge sort algorithm implemented without recursion
*
* the best time: n * log(n)
* average time: n * log(n)
* worst time: n * log(n)
*
* amount of memory: n
*
*/
fun <T : Comparable<T>> Array<T>.mergeSort() {
val temporaryArray = this.copyOf()
@@ -1,13 +1,14 @@
package sorting
/**
* merge sort algorithm
* merge sort algorithm implemented with recursion
*
* worst time: n * log(n)
* the best time: n * log(n)
* average time: n * log(n)
* worst time: n * log(n)
*
* amount of memory: n
*
*/
fun Array<Int>.mergeSortRecursive() {
+110
View File
@@ -0,0 +1,110 @@
package sorting
import java.lang.Integer.min
/**
* Tim sort algorithm
*
* the best time: n
* average time: n * log(n)
* worst time: n * log(n)
*
* amount of memory: n
*
*/
fun Array<Int>.timSort() {
val size = size
val minrun = minrun(size)
var index = 0
while (index < size) {
insertionSort(this, index, min(index + minrun - 1, size - 1))
index += minrun
}
var mergingSize = minrun
while (mergingSize < size) {
var left = 0
while (left < size) {
val middle = left + mergingSize - 1
val right = min(left + 2 * mergingSize - 1, size - 1)
if (middle < right) {
merge(this, left, middle, right)
}
left += mergingSize * 2
}
mergingSize *= 2
}
}
private fun minrun(n: Int) : Int {
var addedValue = 0
var size = n
if (size >= 64) {
addedValue = addedValue or (size and 1)
size = size.shr(1)
}
return size + addedValue
}
private fun insertionSort(array: Array<Int>, left: Int, right: Int) {
var outerIndex = left + 1
while (outerIndex <= right) {
val temporaryValue = array[outerIndex]
var innerIndex = outerIndex - 1
while (innerIndex >= left && array[innerIndex] > temporaryValue) {
array[innerIndex + 1] = array[innerIndex]
innerIndex--
}
array[innerIndex + 1] = temporaryValue
outerIndex++
}
}
private fun merge(array: Array<Int>, left: Int, middle: Int, right: Int) {
val leftLengthArray = middle - left + 1
val rightLengthArray = right - middle
var index = 0
var leftArray = Array(leftLengthArray) { 0 }
while (index < leftLengthArray) {
leftArray[index] = array[left + index]
index++
}
index = 0
var rightArray = Array(rightLengthArray) { 0 }
while (index < rightLengthArray) {
rightArray[index] = array[middle + 1 + index]
index++
}
var leftArrayIndex = 0
var rightArrayIndex = 0
index = 0
while (leftArrayIndex < leftLengthArray && rightArrayIndex < rightLengthArray) {
if (leftArray[leftArrayIndex] <= rightArray[rightArrayIndex]) {
array[index] = leftArray[leftArrayIndex]
leftArrayIndex++
} else {
array[index] = rightArray[rightArrayIndex]
rightArrayIndex++
}
index++
}
while (leftArrayIndex < leftLengthArray) {
array[index] = leftArray[leftArrayIndex]
leftArrayIndex++
index++
}
while (rightArrayIndex < rightLengthArray) {
array[index] = rightArray[rightArrayIndex]
rightArrayIndex++
index++
}
}
+26 -23
View File
@@ -3,10 +3,13 @@ package structures
import java.lang.IllegalStateException
/**
* структура данных: динамический массив
* data structure: dynamic array
*
* описание: обертка над обычным массивом, в которой осуществляется проверка индексов
* и при переполнении массива, его размер увеличивается динамически
* description: wrapper over a regular array, in which indexes are checked and
* when the array overflows, its size increases dynamically
*
* @constructor
* @param capacity initial array size
*/
class DynamicArray(private var capacity: Int = 10) {
@@ -14,11 +17,11 @@ class DynamicArray(private var capacity: Int = 10) {
private var index = 0
/**
* добавляет новый элемент в массив
* add a new element in array
*
* если массив не может вместить новый элемент, то его размер динамически увеличивается
* if the array cannot accommodate the new element, then its size is dynamically increased
*
* @value - элемент
* @param value - element
*/
fun add(value: Int) {
if (index < data.size - 1) {
@@ -30,9 +33,9 @@ class DynamicArray(private var capacity: Int = 10) {
}
/**
* удаляет элемент из массива и сдвигает на его место последующие
* removes an element from the array and shifts subsequent elements in its place
*
* @value - элемент
* @param value - element
*/
fun remove(value: Int) : Boolean {
val foundedIndex = data.indexOf(value)
@@ -46,21 +49,21 @@ class DynamicArray(private var capacity: Int = 10) {
}
/**
* проверяет на существование элемента в массиве
* checks for the existence of an element in an array
*
* @value - элемент
* @param value - element
*
* @return возвращает true, если элемент присутствует в массиве
* @return returns true if the element is present in the array
*/
fun contains(value: Int) = data.contains(value)
/**
* устанавливает новое значения элемента для указанного индекса
* sets the new element value at the specified index
*
* @index - индекс элемента
* @value - новое значение элемента
* @param index - element index
* @param value - the new value of the element
*
* @return возвращает true, если элемент был успешно изменен
* @return returns true if the element was successfully modified
*/
fun set(index: Int, value: Int) : Boolean {
if (isBound(index)) {
@@ -72,11 +75,11 @@ class DynamicArray(private var capacity: Int = 10) {
/**
* возвращает значение элемента по индексу или генерирует исключение, если некорректный индекс
* returns the value of the element by index, or throws an exception if the index is invalid
*
* @index - индекс элемента
* @param index - element index
*
* @return возвращает значение элемента по индексу
* @return returns the value of an element by index
*/
fun get(index: Int) : Int {
if (isBound(index)) {
@@ -87,23 +90,23 @@ class DynamicArray(private var capacity: Int = 10) {
}
/**
* возвращает размер массива
* returns the size of the array
*
* @return возвращает размер массива
*/
fun capacity() = capacity
/**
* проверка на корретный индекс
* check for correct index
*
* @return возвращает true, если индекс входит в диапазон доступных индексов
* @return returns true if the index is within the range of available indexes
*/
private fun isBound(i: Int) = i in 0 until index
override fun toString() = data.joinToString(", ")
/**
* увеличивает размер массива, когда его нехватает
* increases the size of an array when there is not enough to add new elements
*
*/
private fun increaseSize() {
capacity *= 2
+2
View File
@@ -6,9 +6,11 @@ import java.util.LinkedList
* data structure: graph
*
* description: a graph is made up of vertices connected by edges
*
*/
class Graph<T> {
private val data = mutableMapOf<Vertex<T>, MutableList<Vertex<T>>>()
/**
+51
View File
@@ -0,0 +1,51 @@
package sorting
import org.junit.Test
import org.junit.jupiter.api.Assertions
class TimSortTest {
@Test
fun test_reversed_array() {
val expected = TestUtils.list(100000)
val actual = expected.reversed().toTypedArray()
actual.timSort()
Assertions.assertEquals(expected, actual.toList())
}
@Test
fun test_random_array() {
val actual = TestUtils.randomArray(50000)
val expected = actual.sorted()
actual.timSort()
Assertions.assertEquals(expected, actual.toList())
}
@Test
fun test_shuffled_array() {
val expected = TestUtils.sortedArray(100000)
val actual = expected.copyOf()
actual.shuffle()
actual.timSort()
Assertions.assertEquals(expected.toList(), actual.toList())
}
@Test
fun test_sorted_array() {
val actual = TestUtils.sortedArray(100000)
val expected = actual.toList()
actual.timSort()
Assertions.assertEquals(expected, actual.toList())
}
}