Lua Program to Implement Tim Sort

Lua Program to Implement Tim Sort

Tim Sort is a modern and very practical sorting algorithm that was designed to work well with real-world data. It is a hybrid algorithm, which means it combines ideas from Insertion Sort and Merge Sort. The main goal of Tim Sort is to take advantage of data that is already partially sorted, which is very common in everyday programs. Because of this smart behavior, Tim Sort is fast, stable, and reliable.

This algorithm matters a lot because it is used behind the scenes in many popular programming languages and systems. Languages like Python and Java use Tim Sort for sorting lists and arrays. Learning how Tim Sort works in Lua helps beginners understand how simple algorithms can be combined to create something powerful. It also builds a strong foundation for learning advanced sorting techniques while still keeping things friendly and understandable.

Program 1: Basic Tim Sort using loops

This first program shows a simple and beginner-friendly version of Tim Sort using loops. It focuses on the main idea of splitting the array into small runs and sorting them before merging.

-- Basic Tim Sort in Lua

local RUN = 32

function insertionSort(arr, left, right)

    for i = left + 1, right do

        local temp = arr[i]
        local j = i - 1

        while j >= left and arr[j] > temp do
            arr[j + 1] = arr[j]
            j = j - 1
        end

        arr[j + 1] = temp

    end

end

function merge(arr, l, m, r)

    local left = {}
    local right = {}

    for i = l, m do
        table.insert(left, arr[i])
    end

    for i = m + 1, r do
        table.insert(right, arr[i])
    end

    local i, j, k = 1, 1, l

    while i <= #left and j <= #right do

        if left[i] <= right[j] then

            arr[k] = left[i]
            i = i + 1

        else

            arr[k] = right[j]
            j = j + 1

        end

        k = k + 1

    end

    while i <= #left do

        arr[k] = left[i]
        i = i + 1
        k = k + 1

    end

    while j <= #right do

        arr[k] = right[j]
        j = j + 1
        k = k + 1

    end

end

function timSort(arr)

    local n = #arr

    for i = 1, n, RUN do
        insertionSort(arr, i, math.min(i + RUN - 1, n))
    end

    local size = RUN

    while size < n do

        for left = 1, n, 2 * size do

            local mid = left + size - 1
            local right = math.min(left + 2 * size - 1, n)

            if mid < right then
                merge(arr, left, mid, right)
            end

        end

        size = size * 2

    end

end

local data = {5, 21, 7, 23, 19, 10, 3}
timSort(data)

for _, v in ipairs(data) do
    io.write(v .. " ")
end

This program works by first sorting small parts of the array using Insertion Sort. After that, it merges these sorted parts together just like Merge Sort. Beginners can understand this as sorting small chunks first, then carefully joining them into one sorted list.

Program 2: Tim Sort with clearer structure and comments

This version of Tim Sort keeps the same logic but focuses on clarity. The structure is easier to follow, making it more comfortable for beginners.

-- Tim Sort with clearer structure

local RUN = 32

function insertionSort(arr, startIndex, endIndex)

    for i = startIndex + 1, endIndex do

        local key = arr[i]
        local j = i - 1

        while j >= startIndex and arr[j] > key do
            arr[j + 1] = arr[j]
            j = j - 1
        end

        arr[j + 1] = key

    end

end

function merge(arr, left, middle, right)

    local leftPart = {}
    local rightPart = {}

    for i = left, middle do
        leftPart[#leftPart + 1] = arr[i]
    end

    for i = middle + 1, right do
        rightPart[#rightPart + 1] = arr[i]
    end

    local i, j, k = 1, 1, left

    while i <= #leftPart and j <= #rightPart do

        if leftPart[i] <= rightPart[j] then

            arr[k] = leftPart[i]
            i = i + 1

        else

            arr[k] = rightPart[j]
            j = j + 1

        end

        k = k + 1

    end

    while i <= #leftPart do

        arr[k] = leftPart[i]
        i = i + 1
        k = k + 1

    end

    while j <= #rightPart do

        arr[k] = rightPart[j]
        j = j + 1
        k = k + 1

    end

end

function timSort(arr)

    local length = #arr

    for i = 1, length, RUN do
        insertionSort(arr, i, math.min(i + RUN - 1, length))
    end

    local size = RUN

    while size < length do

        for left = 1, length, size * 2 do

            local mid = left + size - 1
            local right = math.min(left + size * 2 - 1, length)

            if mid < right then
                merge(arr, left, mid, right)
            end

        end

        size = size * 2

    end

end

local values = {40, 12, 34, 25, 9, 1}
timSort(values)

for i = 1, #values do
    print(values[i])
end

This version is useful because it emphasizes readability. Beginners can more easily trace how data flows through the functions. Clear structure helps reduce confusion when learning a complex algorithm like Tim Sort.

Program 3: Tim Sort with printed progress

This program prints the array at different stages so learners can see how Tim Sort improves order step by step.

-- Tim Sort with progress output

local RUN = 32

function insertionSort(arr, l, r)

    for i = l + 1, r do

        local temp = arr[i]
        local j = i - 1

        while j >= l and arr[j] > temp do
            arr[j + 1] = arr[j]
            j = j - 1
        end

        arr[j + 1] = temp

    end

end

function merge(arr, l, m, r)

    local left, right = {}, {}

    for i = l, m do left[#left + 1] = arr[i] end
    for i = m + 1, r do right[#right + 1] = arr[i] end

    local i, j, k = 1, 1, l

    while i <= #left and j <= #right do

        if left[i] <= right[j] then

            arr[k] = left[i]
            i = i + 1

        else

            arr[k] = right[j]
            j = j + 1

        end

        k = k + 1

    end

    while i <= #left do

        arr[k] = left[i]
        i = i + 1
        k = k + 1

    end

    while j <= #right do

        arr[k] = right[j]
        j = j + 1
        k = k + 1

    end

end

function timSort(arr)

    local n = #arr

    for i = 1, n, RUN do
        insertionSort(arr, i, math.min(i + RUN - 1, n))
    end

    print("After insertion sort runs:")
    for _, v in ipairs(arr) do io.write(v .. " ") end
    print()

    local size = RUN

    while size < n do

        for left = 1, n, size * 2 do

            local mid = left + size - 1
            local right = math.min(left + size * 2 - 1, n)

            if mid < right then
                merge(arr, left, mid, right)
            end

        end

        size = size * 2

    end

end

local sample = {8, 4, 6, 2, 9, 1, 5}
timSort(sample)

-- final sorted output
print("\nFinal sorted data:")

for _, v in ipairs(sample) do
    io.write(v .. " ")
end

print()

Seeing the array change helps beginners understand what Tim Sort is doing internally. It turns an abstract idea into something visual and logical. This makes learning more enjoyable and less intimidating.

Program 4: Tim Sort as a reusable utility

This version focuses on making Tim Sort easy to reuse in other Lua projects. It keeps the logic clean and practical.

-- Reusable Tim Sort utility

local RUN = 32

function timSort(arr)

    local function insertionSort(a, left, right)

        for i = left + 1, right do

            local key = a[i]
            local j = i - 1

            while j >= left and a[j] > key do
                a[j + 1] = a[j]
                j = j - 1
            end

            a[j + 1] = key

        end

    end

    local function merge(a, l, m, r)

        local temp = {}
        local i, j = l, m + 1

        while i <= m and j <= r do

            if a[i] <= a[j] then
                temp[#temp + 1] = a[i]
                i = i + 1
            else
                temp[#temp + 1] = a[j]
                j = j + 1
            end

        end

        while i <= m do
            temp[#temp + 1] = a[i]
            i = i + 1
        end

        while j <= r do
            temp[#temp + 1] = a[j]
            j = j + 1
        end

        for k = 1, #temp do
            a[l + k - 1] = temp[k]
        end

    end

    local n = #arr

    for i = 1, n, RUN do
        insertionSort(arr, i, math.min(i + RUN - 1, n))
    end

    local size = RUN

    while size < n do

        for left = 1, n, size * 2 do

            local mid = left + size - 1
            local right = math.min(left + size * 2 - 1, n)

            if mid < right then
                merge(arr, left, mid, right)
            end

        end

        size = size * 2

    end

end

local numbers = {11, 3, 7, 2, 9, 4}
timSort(numbers)

for _, v in ipairs(numbers) do
    io.write(v .. " ")
end

This program is useful when building larger Lua applications. Beginners can simply copy this function and use it whenever sorting is needed. It shows how professional code is often written for reuse.

Program 5: Tim Sort with negative and floating-point numbers

Tim Sort works naturally with negative and decimal values in Lua. This final program demonstrates that behavior clearly.

-- Tim Sort with negative and floating-point numbers

local RUN = 32

function insertionSort(arr, l, r)

    for i = l + 1, r do

        local temp = arr[i]
        local j = i - 1

        while j >= l and arr[j] > temp do
            arr[j + 1] = arr[j]
            j = j - 1
        end

        arr[j + 1] = temp

    end

end

function merge(arr, l, m, r)

    local temp = {}
    local i, j = l, m + 1

    while i <= m and j <= r do

        if arr[i] <= arr[j] then
            temp[#temp + 1] = arr[i]
            i = i + 1
        else
            temp[#temp + 1] = arr[j]
            j = j + 1
        end

    end

    while i <= m do
        temp[#temp + 1] = arr[i]
        i = i + 1
    end

    while j <= r do
        temp[#temp + 1] = arr[j]
        j = j + 1
    end

    for k = 1, #temp do
        arr[l + k - 1] = temp[k]
    end

end

function timSort(arr)

    local n = #arr

    for i = 1, n, RUN do
        insertionSort(arr, i, math.min(i + RUN - 1, n))
    end

    local size = RUN

    while size < n do

        for left = 1, n, size * 2 do

            local mid = left + size - 1
            local right = math.min(left + size * 2 - 1, n)

            if mid < right then
                merge(arr, left, mid, right)
            end

        end

        size = size * 2

    end

end

local mixed = {3.2, -1.5, 4.8, 0, -6.3, 2.1}
timSort(mixed)

for _, v in ipairs(mixed) do
    io.write(v .. " ")
end

This example proves that Tim Sort does not need special changes to support negative or floating-point numbers. Lua handles numeric comparisons smoothly, so the algorithm works as expected. Beginners can safely use Tim Sort for real-world numeric data.

Frequently Asked Questions (FAQ)

This section answers common beginner questions about Tim Sort in Lua.

Q1. Is Tim Sort faster than Merge Sort?
Tim Sort is often faster in real-world cases because it takes advantage of existing order in data. Merge Sort always does the same amount of work.

Q2. Is Tim Sort stable?
Yes, Tim Sort is a stable sorting algorithm. Equal values keep their original order.

Q3. Is Tim Sort hard to learn?
Tim Sort looks complex at first, but breaking it into insertion and merge steps makes it easier to understand.

Q4. Why is Tim Sort used in many languages?
It is fast, reliable, and performs very well on real data that is partially sorted.

Q5. Can Tim Sort be used in small programs?
Yes, Tim Sort works well in both small and large programs, especially when performance matters.

Conclusion

Tim Sort is a powerful and practical sorting algorithm that combines the best ideas from simpler techniques. In this article, you learned how to implement Tim Sort in Lua using several complete programs, starting from basic versions and moving toward more reusable and flexible ones. You also saw that Tim Sort easily handles negative and floating-point numbers.

By practicing these examples and experimenting with your own data, you will gain confidence in both Lua programming and sorting algorithms. Keep exploring, keep coding, and enjoy learning how smart algorithms solve real problems.

Scroll to Top