added a new sorting algorithm Tim sort, added comments for MergeSort.kt file, edited some old comments
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
1
.idea/gradle.xml
generated
1
.idea/gradle.xml
generated
@ -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>
|
||||
|
||||
@ -1,7 +0,0 @@
|
||||
import sorting.mergeSort
|
||||
|
||||
fun main() {
|
||||
val array = arrayOf(5, 4, 3, 2, 1, 0)
|
||||
array.mergeSort()
|
||||
print(array.toList())
|
||||
}
|
||||
@ -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
src/main/kotlin/sorting/TimSort.kt
Normal file
110
src/main/kotlin/sorting/TimSort.kt
Normal 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++
|
||||
}
|
||||
}
|
||||
@ -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
|
||||
|
||||
@ -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
src/test/kotlin/sorting/TimSortTest.kt
Normal file
51
src/test/kotlin/sorting/TimSortTest.kt
Normal 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())
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user