123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976 |
- -- lua-sort
- -- Helper function to swap two values in a table
- local function swap(arr, i, j)
- local temp = arr[i]
- arr[i] = arr[j]
- arr[j] = temp
- end
- -- Bubble Sort algorithm
- local function bubbleSort(arr)
- local n = #arr
- for i = 1, n - 1 do
- for j = 1, n - i do
- if arr[j] > arr[j + 1] then
- swap(arr, j, j + 1)
- end
- end
- end
- end
- -- Insertion Sort algorithm
- local function insertionSort(arr)
- local n = #arr
- for i = 2, n do
- local key = arr[i]
- local j = i - 1
- while j > 0 and arr[j] > key do
- arr[j + 1] = arr[j]
- j = j - 1
- end
- arr[j + 1] = key
- end
- end
- -- Selection Sort algorithm
- local function selectionSort(arr)
- local n = #arr
- for i = 1, n - 1 do
- local minIndex = i
- for j = i + 1, n do
- if arr[j] < arr[minIndex] then
- minIndex = j
- end
- end
- swap(arr, i, minIndex)
- end
- end
- -- Merge Sort algorithm
- local function mergeSort(arr)
- local function merge(left, right)
- local result = {}
- local i = 1
- local j = 1
- while i <= #left and j <= #right do
- if left[i] <= right[j] then
- table.insert(result, left[i])
- i = i + 1
- else
- table.insert(result, right[j])
- j = j + 1
- end
- end
- for k = i, #left do
- table.insert(result, left[k])
- end
- for k = j, #right do
- table.insert(result, right[k])
- end
- return result
- end
- local function divide(arr)
- if #arr <= 1 then
- return arr
- end
- local mid = math.floor(#arr / 2)
- local left = {}
- local right = {}
- for i = 1, mid do
- table.insert(left, arr[i])
- end
- for i = mid + 1, #arr do
- table.insert(right, arr[i])
- end
- left = divide(left)
- right = divide(right)
- return merge(left, right)
- end
- local sortedArr = divide(arr)
- for i = 1, #arr do
- arr[i] = sortedArr[i]
- end
- end
- -- Quick Sort algorithm
- local function partition(arr, low, high)
- local pivot = arr[high]
- local i = low - 1
- for j = low, high - 1 do
- if arr[j] <= pivot then
- i = i + 1
- swap(arr, i, j)
- end
- end
- swap(arr, i + 1, high)
- return i + 1
- end
- local function quickSort(arr, low, high)
- if low < high then
- local pivot = partition(arr, low, high)
- quickSort(arr, low, pivot - 1)
- quickSort(arr, pivot + 1, high)
- end
- end
- -- Shell Sort algorithm
- local function shellSort(arr)
- local n = #arr
- local gap = math.floor(n / 2)
- while gap > 0 do
- for i = gap + 1, n do
- local temp = arr[i]
- local j = i
- while j > gap and arr[j - gap] > temp do
- arr[j] = arr[j - gap]
- j = j - gap
- end
- arr[j] = temp
- end
- gap = math.floor(gap / 2)
- end
- end
- -- Counting Sort algorithm
- local function countingSort(arr, minVal, maxVal)
- local counts = {}
- for i = minVal, maxVal do
- counts[i] = 0
- end
- for i = 1, #arr do
- counts[arr[i]] = counts[arr[i]] + 1
- end
- local sortedIndex = 1
- for i = minVal, maxVal do
- while counts[i] > 0 do
- arr[sortedIndex] = i
- sortedIndex = sortedIndex + 1
- counts[i] = counts[i] - 1
- end
- end
- end
- -- Heap Sort algorithm
- local function heapSort(arr)
- local n = #arr
- local function heapify(arr, n, i)
- local largest = i
- local left = 2 * i
- local right = 2 * i + 1
- if left <= n and arr[left] > arr[largest] then
- largest = left
- end
- if right <= n and arr[right] > arr[largest] then
- largest = right
- end
- if largest ~= i then
- swap(arr, i, largest)
- heapify(arr, n, largest)
- end
- end
- for i = math.floor(n / 2), 1, -1 do
- heapify(arr, n, i)
- end
- for i = n, 2, -1 do
- swap(arr, 1, i)
- heapify(arr, i - 1, 1)
- end
- end
- -- Radix Sort algorithm
- local function radixSort(arr)
- local function countingSortByDigit(arr, exp)
- local counts = {}
- for i = 0, 9 do
- counts[i] = 0
- end
- for i = 1, #arr do
- local digit = math.floor(arr[i] / exp) % 10
- counts[digit] = counts[digit] + 1
- end
- for i = 1, 9 do
- counts[i] = counts[i] + counts[i - 1]
- end
- local output = {}
- for i = #arr, 1, -1 do
- local digit = math.floor(arr[i] / exp) % 10
- output[counts[digit]] = arr[i]
- counts[digit] = counts[digit] - 1
- end
- for i = 1, #arr do
- arr[i] = output[i]
- end
- end
- local maxVal = math.max(unpack(arr))
- local exp = 1
- while math.floor(maxVal / exp) > 0 do
- countingSortByDigit(arr, exp)
- exp = exp * 10
- end
- end
- -- Introsort algorithm
- local function introsortSort(arr, low, high, maxDepth)
- if high - low <= 16 then
- insertionSort(arr, low, high)
- elseif maxDepth == 0 then
- heapSort(arr, low, high)
- else
- local pivot = partition(arr, low, high)
- introsortSort(arr, low, pivot - 1, maxDepth - 1)
- introsortSort(arr, pivot + 1, high, maxDepth - 1)
- end
- end
- local function introSort(arr)
- local maxDepth = math.floor(math.log(#arr, 2))
- introsortSort(arr, 1, #arr, maxDepth)
- end
- -- Block Sort algorithm
- local function blockSort(arr)
- local blockSize = math.floor(math.sqrt(#arr))
-
- -- Divide the array into blocks
- local blocks = {}
- for i = 1, #arr, blockSize do
- local block = {}
- for j = i, math.min(i + blockSize - 1, #arr) do
- table.insert(block, arr[j])
- end
- table.insert(blocks, block)
- end
-
- -- Sort each block
- for _, block in ipairs(blocks) do
- insertionSort(block)
- end
-
- -- Merge the sorted blocks
- local result = {}
- while #blocks > 0 do
- local minBlock = 1
- for i = 2, #blocks do
- if blocks[i][1] < blocks[minBlock][1] then
- minBlock = i
- end
- end
- table.insert(result, blocks[minBlock][1])
- table.remove(blocks[minBlock], 1)
- if #blocks[minBlock] == 0 then
- table.remove(blocks, minBlock)
- end
- end
-
- -- Update the original array with the sorted result
- for i = 1, #arr do
- arr[i] = result[i]
- end
- end
- -- Timsort algorithm
- local MIN_MERGE = 32
- local function calculateMinRun(n)
- local r = 0
- while n >= MIN_MERGE do
- r = bit.bor(r, bit.band(n, 1))
- n = bit.rshift(n, 1)
- end
- return n + r
- end
- local function insertionSortTimSort(arr, left, right)
- for i = left + 1, right do
- local key = arr[i]
- local j = i - 1
- while j >= left and arr[j] > key do
- arr[j + 1] = arr[j]
- j = j - 1
- end
- arr[j + 1] = key
- end
- end
- local function mergeTimSort(arr, left, mid, right)
- local len1 = mid - left + 1
- local len2 = right - mid
- local leftArr = {}
- local rightArr = {}
- for i = 1, len1 do
- leftArr[i] = arr[left + i - 1]
- end
- for i = 1, len2 do
- rightArr[i] = arr[mid + i]
- end
- local i = 1
- local j = 1
- local k = left
- while i <= len1 and j <= len2 do
- if leftArr[i] <= rightArr[j] then
- arr[k] = leftArr[i]
- i = i + 1
- else
- arr[k] = rightArr[j]
- j = j + 1
- end
- k = k + 1
- end
- while i <= len1 do
- arr[k] = leftArr[i]
- i = i + 1
- k = k + 1
- end
- while j <= len2 do
- arr[k] = rightArr[j]
- j = j + 1
- k = k + 1
- end
- end
- local function timSort(arr)
- local n = #arr
- local minRun = calculateMinRun(n)
- for i = 1, n, minRun do
- insertionSortTimSort(arr, i, math.min(i + minRun - 1, n))
- end
- local size = minRun
- while size < n do
- for start = 1, n, size * 2 do
- local mid = start + size - 1
- local right = math.min(start + size * 2 - 1, n)
- if mid < right then
- mergeTimSort(arr, start, mid, right)
- end
- end
- size = size * 2
- end
- end
- -- Cubesort algorithm
- local function cubeSort(arr)
- local n = #arr
- -- Find the minimum and maximum values in the array
- local minValue = math.min(unpack(arr))
- local maxValue = math.max(unpack(arr))
- -- Create an array to store the counts of each value
- local counts = {}
- for i = minValue, maxValue do
- counts[i] = 0
- end
- -- Count the occurrences of each value
- for i = 1, n do
- counts[arr[i]] = counts[arr[i]] + 1
- end
- -- Update the array with the sorted values
- local index = 1
- for i = minValue, maxValue do
- while counts[i] > 0 do
- arr[index] = i
- counts[i] = counts[i] - 1
- index = index + 1
- end
- end
- end
- -- Exchange Sort algorithm
- local function exchangeSort(arr)
- local n = #arr
- for i = 1, n - 1 do
- for j = i + 1, n do
- if arr[j] < arr[i] then
- swap(arr, i, j)
- end
- end
- end
- end
- -- Tree Node
- local TreeNode = {}
- TreeNode.__index = TreeNode
- function TreeNode.new(value)
- local node = setmetatable({}, TreeNode)
- node.value = value
- node.left = nil
- node.right = nil
- return node
- end
- -- Insert a value into the tree
- local function insertNode(root, value)
- if root == nil then
- return TreeNode.new(value)
- end
- if value < root.value then
- root.left = insertNode(root.left, value)
- else
- root.right = insertNode(root.right, value)
- end
- return root
- end
- -- In-order traversal of the tree
- local function inorderTraversal(root, arr, index)
- if root ~= nil then
- index = inorderTraversal(root.left, arr, index)
- arr[index] = root.value
- index = index + 1
- index = inorderTraversal(root.right, arr, index)
- end
- return index
- end
- -- Tree Sort algorithm
- local function treeSort(arr)
- local n = #arr
- local root = nil
- -- Construct the binary search tree
- for i = 1, n do
- root = insertNode(root, arr[i])
- end
- -- Perform in-order traversal to get sorted array
- local index = inorderTraversal(root, arr, 1)
- end
- -- Cycle Sort algorithm
- local function cycleSort(arr)
- local n = #arr
- for cycleStart = 1, n - 1 do
- local item = arr[cycleStart]
- local pos = cycleStart
- for i = cycleStart + 1, n do
- if arr[i] < item then
- pos = pos + 1
- end
- end
- if pos == cycleStart then
- -- The item is already in its correct position
- goto continue
- end
- while item == arr[pos] do
- pos = pos + 1
- end
- local temp = arr[pos]
- arr[pos] = item
- item = temp
- while pos ~= cycleStart do
- pos = cycleStart
- for i = cycleStart + 1, n do
- if arr[i] < item then
- pos = pos + 1
- end
- end
- while item == arr[pos] do
- pos = pos + 1
- end
- temp = arr[pos]
- arr[pos] = item
- item = temp
- end
- ::continue::
- end
- end
- -- Helper function to merge two sorted arrays
- local function mergeArrays(arr1, arr2)
- local merged = {}
- local i = 1
- local j = 1
- while i <= #arr1 and j <= #arr2 do
- if arr1[i] <= arr2[j] then
- table.insert(merged, arr1[i])
- i = i + 1
- else
- table.insert(merged, arr2[j])
- j = j + 1
- end
- end
- while i <= #arr1 do
- table.insert(merged, arr1[i])
- i = i + 1
- end
- while j <= #arr2 do
- table.insert(merged, arr2[j])
- j = j + 1
- end
- return merged
- end
- -- Strand Sort algorithm
- local function strandSort(arr)
- local function recursiveSort(sublist)
- if #sublist <= 1 then
- return sublist
- end
- local sorted = { table.remove(sublist, 1) }
- local remaining = {}
- for i = 1, #sublist do
- if sublist[i] >= sorted[#sorted] then
- table.insert(sorted, sublist[i])
- else
- table.insert(remaining, sublist[i])
- end
- end
- return mergeArrays(sorted, recursiveSort(remaining))
- end
- local sortedArr = recursiveSort(arr)
- -- Update the original array
- for i = 1, #arr do
- arr[i] = sortedArr[i]
- end
- end
- -- Helper function to perform a comparison and swap in the tournament
- local function compare(arr, i, j)
- if arr[i] > arr[j] then
- return i
- else
- return j
- end
- end
- -- Helper function to perform a recursive tournament
- local function tournament(arr, start, end_)
- if start == end_ then
- return start
- else
- local mid = math.floor((start + end_) / 2)
- local left = tournament(arr, start, mid)
- local right = tournament(arr, mid + 1, end_)
- return compare(arr, left, right)
- end
- end
- -- Tournament Sort algorithm
- local function tournamentSort(arr)
- local n = #arr
- local sortedArr = {}
- local remaining = n
- while remaining > 0 do
- local winner = tournament(arr, 1, remaining)
- sortedArr[remaining] = arr[winner]
- arr[winner] = arr[remaining]
- remaining = remaining - 1
- end
- -- Update the original array
- for i = 1, n do
- arr[i] = sortedArr[i]
- end
- end
- -- Gnome Sort algorithm
- local function gnomeSort(arr)
- local n = #arr
- local i = 2
- while i <= n do
- if arr[i - 1] <= arr[i] then
- i = i + 1
- else
- swap(arr, i - 1, i)
- if i > 2 then
- i = i - 1
- end
- end
- end
- end
- -- Comb Sort algorithm
- local function combSort(arr)
- local n = #arr
- local gap = n
- local shrink = 1.3
- local sorted = false
- while not sorted do
- gap = math.floor(gap / shrink)
- if gap > 1 then
- sorted = false
- else
- gap = 1
- sorted = true
- end
- local i = 1
- while i + gap <= n do
- if arr[i] > arr[i + gap] then
- swap(arr, i, i + gap)
- sorted = false
- end
- i = i + 1
- end
- end
- end
- -- Cocktail Shaker Sort algorithm
- local function cocktailShakerSort(arr)
- local n = #arr
- local start = 1
- local finish = n
- local swapped = true
- while swapped do
- swapped = false
- -- Perform a forward pass
- for i = start, finish - 1 do
- if arr[i] > arr[i + 1] then
- swap(arr, i, i + 1)
- swapped = true
- end
- end
- -- If no swaps occurred, the array is already sorted
- if not swapped then
- break
- end
- -- Update the end position for the next pass
- finish = finish - 1
- -- Perform a backward pass
- for i = finish - 1, start - 1, -1 do
- if arr[i] > arr[i + 1] then
- swap(arr, i, i + 1)
- swapped = true
- end
- end
- -- Update the start position for the next pass
- start = start + 1
- end
- end
- -- Pigeonhole Sort algorithm
- local function pigeonholeSort(arr)
- local n = #arr
- local minVal = math.min(unpack(arr))
- local maxVal = math.max(unpack(arr))
- local range = maxVal - minVal + 1
- local pigeonholes = {}
- -- Initialize pigeonholes
- for i = 1, range do
- pigeonholes[i] = {}
- end
- -- Distribute elements into pigeonholes
- for i = 1, n do
- local value = arr[i]
- local index = value - minVal + 1
- table.insert(pigeonholes[index], value)
- end
- -- Gather sorted elements from pigeonholes
- local sortedIndex = 1
- for i = 1, range do
- local hole = pigeonholes[i]
- for j = 1, #hole do
- arr[sortedIndex] = hole[j]
- sortedIndex = sortedIndex + 1
- end
- end
- end
- -- Bucket Sort algorithm (uniform keys)
- local function bucketSortUniform(arr)
- local n = #arr
- local numBuckets = n -- Number of buckets equals the number of elements
- -- Create empty buckets
- local buckets = {}
- for i = 1, numBuckets do
- buckets[i] = {}
- end
- -- Distribute elements into buckets
- for i = 1, n do
- local index = math.floor(arr[i] * numBuckets) + 1
- table.insert(buckets[index], arr[i])
- end
- -- Sort individual buckets
- for i = 1, numBuckets do
- table.sort(buckets[i])
- end
- -- Concatenate sorted buckets
- local index = 1
- for i = 1, numBuckets do
- for j = 1, #buckets[i] do
- arr[index] = buckets[i][j]
- index = index + 1
- end
- end
- end
- -- Bucket Sort algorithm (integer keys)
- local function bucketSortInteger(arr)
- local n = #arr
- local maxVal = math.max(unpack(arr))
- local numBuckets = maxVal + 1
- -- Create empty buckets
- local buckets = {}
- for i = 1, numBuckets do
- buckets[i] = {}
- end
- -- Distribute elements into buckets
- for i = 1, n do
- local index = arr[i] + 1
- table.insert(buckets[index], arr[i])
- end
- -- Sort individual buckets (if needed)
- for i = 1, numBuckets do
- if #buckets[i] > 1 then
- table.sort(buckets[i])
- end
- end
- -- Concatenate sorted buckets
- local index = 1
- for i = 1, numBuckets do
- for j = 1, #buckets[i] do
- arr[index] = buckets[i][j]
- index = index + 1
- end
- end
- end
- -- Spreadsort algorithm
- local function spreadSort(arr)
- local n = #arr
- local numKeys = n -- Number of keys equals the number of elements
- -- Create auxiliary arrays
- local indexes = {}
- local counts = {}
- -- Initialize indexes and counts arrays
- for i = 1, numKeys do
- indexes[i] = i
- counts[i] = 0
- end
- -- Count the occurrences of each key
- for i = 1, n do
- local key = arr[i]
- counts[key] = counts[key] + 1
- end
- -- Calculate the starting index for each key
- local sum = 0
- for i = 1, numKeys do
- local count = counts[i]
- counts[i] = sum
- sum = sum + count
- end
- -- Permute the elements based on their keys
- local sortedArr = {}
- for i = 1, n do
- local key = arr[i]
- local index = counts[key] + indexes[key]
- sortedArr[index] = arr[i]
- indexes[key] = indexes[key] + 1
- end
- -- Copy the sorted elements back to the original array
- for i = 1, n do
- arr[i] = sortedArr[i]
- end
- end
- -- Burstsort algorithm
- local function burstSort(arr)
- local n = #arr
- local blockSize = math.floor(math.sqrt(n)) -- Size of each block
- -- Create blocks
- local blocks = {}
- local numBlocks = math.ceil(n / blockSize)
- for i = 1, numBlocks do
- local block = {}
- local start = (i - 1) * blockSize + 1
- local stop = math.min(start + blockSize - 1, n)
- for j = start, stop do
- table.insert(block, arr[j])
- end
- table.sort(block)
- table.insert(blocks, block)
- end
- -- Merge the sorted blocks into the original array
- local index = 1
- while #blocks > 0 do
- local minBlockIndex = 1
- for i = 2, #blocks do
- if blocks[i][1] < blocks[minBlockIndex][1] then
- minBlockIndex = i
- end
- end
- local minBlock = blocks[minBlockIndex]
- arr[index] = minBlock[1]
- table.remove(minBlock, 1)
- index = index + 1
- if #minBlock == 0 then
- table.remove(blocks, minBlockIndex)
- end
- end
- end
- -- Flashsort algorithm
- local function flashSort(arr)
- local n = #arr
- local minVal = arr[1]
- local maxVal = arr[1]
- -- Find the minimum and maximum values
- for i = 2, n do
- if arr[i] < minVal then
- minVal = arr[i]
- elseif arr[i] > maxVal then
- maxVal = arr[i]
- end
- end
- -- Calculate the number of classes and the class width
- local numClasses = math.floor(0.45 * n)
- local classWidth = (maxVal - minVal) / numClasses
- -- Count the number of elements in each class
- local counts = {}
- for i = 1, numClasses do
- counts[i] = 0
- end
- for i = 1, n do
- local classIndex = math.floor((arr[i] - minVal) / classWidth) + 1
- counts[classIndex] = counts[classIndex] + 1
- end
- -- Calculate the starting position of each class
- local sum = 0
- for i = 1, numClasses do
- local count = counts[i]
- counts[i] = sum
- sum = sum + count
- end
- -- Permute the elements based on their classes
- while counts[1] < n do
- local currentIndex = counts[1] + 1
- local currentElement = arr[currentIndex]
- local classIndex = math.floor((currentElement - minVal) / classWidth) + 1
- if classIndex ~= 1 then
- local swapIndex = counts[classIndex]
- swap(arr, currentIndex, swapIndex)
- else
- currentIndex = currentIndex + 1
- end
- counts[classIndex] = counts[classIndex] + 1
- end
- -- Insertion sort on each class
- for i = 2, numClasses do
- local start = counts[i - 1] + 1
- local stop = counts[i]
- for j = start + 1, stop do
- local key = arr[j]
- local k = j - 1
- while k >= start and arr[k] > key do
- arr[k + 1] = arr[k]
- k = k - 1
- end
- arr[k + 1] = key
- end
- end
- end
- return {
- bubbleSort = bubbleSort,
- insertionSort = insertionSort,
- selectionSort = selectionSort,
- mergeSort = mergeSort,
- quickSort = quickSort,
- shellSort = shellSort,
- countingSort = countingSort,
- heapSort = heapSort,
- radixSort = radixSort,
- introSort = introSort,
- blockSort = blockSort,
- timSort = timSort,
- cubeSort = cubeSort,
- exchangeSort = exchangeSort,
- treeSort = treeSort,
- cycleSort = cycleSort,
- strandSort = strandSort,
- tournamentSort = tournamentSort,
- gnomeSort = gnomeSort,
- combSort = combSort,
- cocktailShakerSort = cocktailShakerSort,
- pigeonholeSort = pigeonholeSort,
- bucketSortUniform = bucketSortUniform,
- bucketSortInteger = bucketSortInteger,
- spreadSort = spreadSort,
- burstSort = burstSort,
- flashSort = flashSort
- }
|