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

1
.idea/gradle.xml generated
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>

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())
}

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()

View File

@ -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() {

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++
}
}

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

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>>>()
/**

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())
}
}