Files
JavaScript/Sorts/TimSort.js
Roland Hummel 86d333ee94 feat: Test running overhaul, switch to Prettier & reformat everything (#1407)
* chore: Switch to Node 20 + Vitest

* chore: migrate to vitest mock functions

* chore: code style (switch to prettier)

* test: re-enable long-running test

Seems the switch to Node 20 and Vitest has vastly improved the code's and / or the test's runtime!

see #1193

* chore: code style

* chore: fix failing tests

* Updated Documentation in README.md

* Update contribution guidelines to state usage of Prettier

* fix: set prettier printWidth back to 80

* chore: apply updated code style automatically

* fix: set prettier line endings to lf again

* chore: apply updated code style automatically

---------

Co-authored-by: github-actions <${GITHUB_ACTOR}@users.noreply.github.com>
Co-authored-by: Lars Müller <34514239+appgurueu@users.noreply.github.com>
2023-10-04 02:38:19 +05:30

116 lines
3.0 KiB
JavaScript

/**
* @function Timsort is a hybrid stable sorting algorithm, derived from merge sort and insertion sort,
* designed to perform well on many kinds of real-world data.
* It was implemented by Tim Peters in 2002 for use in the Python programming language.
* It is also used to sort arrays of non-primitive type in Java SE 7,
* on the Android platform, in GNU Octave, on V8, Swift and Rust.
* 1) It sorts small partitions using Insertion Sort.
* 2) Merges the partition using Merge Sort.
* @see [Timsort](https://en.wikipedia.org/wiki/Timsort)
* @param {Array} array
*/
const Timsort = (array) => {
// Default size of a partition
const RUN = 32
const n = array.length
// Sorting the partitions using Insertion Sort
for (let i = 0; i < n; i += RUN) {
InsertionSort(array, i, Math.min(i + RUN - 1, n - 1))
}
for (let size = RUN; size < n; size *= 2) {
for (let left = 0; left < n; left += 2 * size) {
const mid = left + size - 1
const right = Math.min(left + 2 * size - 1, n - 1)
Merge(array, left, mid, right)
}
}
return array
}
/**
* @function performs insertion sort on the partition
* @param {Array} array array to be sorted
* @param {Number} left left index of partition
* @param {Number} right right index of partition
*/
const InsertionSort = (array, left, right) => {
for (let i = left + 1; i <= right; i++) {
const key = array[i]
let j = i - 1
while (j >= left && array[j] > key) {
array[j + 1] = array[j]
j--
}
array[j + 1] = key
}
}
/**
* @function merges two sorted partitions
* @param {Array} array array to be sorted
* @param {Number} left left index of partition
* @param {Number} mid mid index of partition
* @param {Number} right right index of partition
*/
const Merge = (array, left, mid, right) => {
if (mid >= right) return
const len1 = mid - left + 1
const len2 = right - mid
const larr = Array(len1)
const rarr = Array(len2)
for (let i = 0; i < len1; i++) {
larr[i] = array[left + i]
}
for (let i = 0; i < len2; i++) {
rarr[i] = array[mid + 1 + i]
}
let i = 0
let j = 0
let k = left
while (i < larr.length && j < rarr.length) {
if (larr[i] < rarr[j]) {
array[k++] = larr[i++]
} else {
array[k++] = rarr[j++]
}
}
while (i < larr.length) {
array[k++] = larr[i++]
}
while (j < rarr.length) {
array[k++] = rarr[j++]
}
}
/**
* @example Test of Timsort functions.
* Data is randomly generated.
* Return "RIGHT" if it works as expected,
* otherwise "FAULTY"
*/
const demo = () => {
const size = 1000000
const data = Array(size)
for (let i = 0; i < size; i++) {
data[i] = Math.random() * Number.MAX_SAFE_INTEGER
}
const isSorted = function (array) {
const n = array.length
for (let i = 0; i < n - 1; i++) {
if (array[i] > array[i + 1]) return false
}
return true
}
Timsort(data)
if (isSorted(data)) {
return 'RIGHT'
} else {
return 'FAULTY'
}
}
export { Timsort, demo }