Lua Program to Implement Merge Sort

Lua Program to Implement Merge Sort

Merge Sort is a powerful and reliable sorting algorithm that follows a very logical idea. Instead of trying to sort everything at once, Merge Sort breaks a large problem into smaller pieces, sorts those pieces, and then merges them back together in the correct order. This divide-and-conquer approach makes Merge Sort much faster and more efficient than simple algorithms like Bubble Sort or Selection Sort, especially when working with large amounts of data.

In Lua programming, learning Merge Sort is important because it introduces you to recursion, problem decomposition, and clean algorithm design. Merge Sort is commonly used in real-world systems such as databases, search engines, and file processing tools where performance and consistency matter. Even if you are a beginner, understanding Merge Sort will greatly improve the way you think about solving complex problems step by step.

Program 1: Basic Recursive Merge Sort in Lua

This program shows the most classic way to implement Merge Sort using recursion. It splits the table into smaller parts, sorts them, and then merges them back together.

local function merge(left, right)

    local result = {}
    local i, j = 1, 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

    while i <= #left do

        table.insert(result, left[i])
        i = i + 1

    end

    while j <= #right do

        table.insert(result, right[j])
        j = j + 1

    end

    return result

end

local function mergeSort(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

    return merge(mergeSort(left), mergeSort(right))

end

local numbers = {38, 27, 43, 3, 9, 82, 10}
local sorted = mergeSort(numbers)

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

This code works by repeatedly dividing the table until each part contains only one value. Those small parts are already sorted by nature, so the merge function carefully combines them into a larger sorted table. Beginners can understand this by thinking of it as sorting small piles first and then joining them neatly.

Program 2: Merge Sort with Clear Split and Merge Functions

This program separates the splitting and merging logic more clearly to make the algorithm easier to read and follow.

local function merge(arr, left, mid, right)

    local temp = {}
    local i, j = left, mid + 1

    while i <= mid and j <= right do

        if arr[i] <= arr[j] then

            table.insert(temp, arr[i])
            i = i + 1

        else

            table.insert(temp, arr[j])
            j = j + 1

        end

    end

    while i <= mid do

        table.insert(temp, arr[i])
        i = i + 1

    end

    while j <= right do

        table.insert(temp, arr[j])
        j = j + 1

    end

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

end

local function mergeSort(arr, left, right)

    if left < right then

        local mid = math.floor((left + right) / 2)

        mergeSort(arr, left, mid)
        mergeSort(arr, mid + 1, right)
        merge(arr, left, mid, right)

    end

end

local numbers = {12, 11, 13, 5, 6, 7}
mergeSort(numbers, 1, #numbers)

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

This version sorts the table in place instead of creating new tables at every step. It helps beginners understand how indexes work in Lua and how data can be modified directly. This style is closer to how Merge Sort is implemented in performance-focused systems.

Program 3: Merge Sort with Step-by-Step Output

This program prints intermediate results so you can see how Merge Sort builds the sorted table.

local function merge(left, right)

    local result = {}
    local i, j = 1, 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

    while i <= #left do

        table.insert(result, left[i])
        i = i + 1

    end

    while j <= #right do

        table.insert(result, right[j])
        j = j + 1

    end

    return result

end

local function mergeSort(arr)

    if #arr <= 1 then
        return arr
    end

    local mid = math.floor(#arr / 2)
    local left = mergeSort({table.unpack(arr, 1, mid)})
    local right = mergeSort({table.unpack(arr, mid + 1)})

    local merged = merge(left, right)

    for i = 1, #merged do
        io.write(merged[i] .. " ")
    end

    print()

    return merged

end

local numbers = {8, 4, 2, 1, 3}
mergeSort(numbers)

By printing each merged result, beginners can visually follow how small sorted parts grow into a full sorted table. This teaching style makes Merge Sort feel less mysterious and more approachable.

Program 4: Merge Sort Wrapped Inside a Reusable Function

This program focuses on clean design by placing the entire logic inside reusable functions.

local function mergeSort(arr)

    if #arr <= 1 then
        return arr
    end

    local mid = math.floor(#arr / 2)
    local left = {}
    local right = {}

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

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

    left = mergeSort(left)
    right = mergeSort(right)

    local result = {}
    local i, j = 1, 1

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

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

            result[#result + 1] = left[i]
            i = i + 1

        else

            result[#result + 1] = right[j]
            j = j + 1

        end

    end

    while i <= #left do

        result[#result + 1] = left[i]
        i = i + 1

    end

    while j <= #right do

        result[#result + 1] = right[j]
        j = j + 1

    end

    return result

end

local numbers = {15, 3, 9, 8, 5, 2}
local sorted = mergeSort(numbers)

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

This approach encourages good programming habits. Beginners learn how to write clean, readable code that can be reused in many projects. It also reinforces the idea of breaking problems into smaller functions.

Program 5: Iterative Merge Sort Using Bottom-Up Approach

This program avoids recursion and uses an iterative method to perform Merge Sort.

local function merge(arr, temp, left, mid, right)

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

    while i <= mid and j <= right do

        if arr[i] <= arr[j] then

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

        else

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

        end

        k = k + 1

    end

    while i <= mid do

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

    end

    while j <= right do

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

    end

    for x = left, right do
        arr[x] = temp[x]
    end

end

local function mergeSort(arr)

    local n = #arr
    local temp = {}

    local size = 1

    while size < n do

        local left = 1

        while left <= n - size do

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

            merge(arr, temp, left, mid, right)
            left = left + 2 * size

        end

        size = size * 2

    end

end

local numbers = {19, 14, 7, 3, 11, 6}
mergeSort(numbers)

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

This bottom-up approach is useful for understanding how Merge Sort can work without recursion. It helps beginners see that algorithms can be implemented in multiple ways while still following the same core idea.

Program 6: Merge Sort for String Values

Merge Sort works just as well with text data. This program sorts strings alphabetically.

local function mergeSort(arr)

    if #arr <= 1 then
        return arr
    end

    local mid = math.floor(#arr / 2)
    local left = mergeSort({table.unpack(arr, 1, mid)})
    local right = mergeSort({table.unpack(arr, mid + 1)})

    local result = {}
    local i, j = 1, 1

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

        if left[i] < right[j] then

            result[#result + 1] = left[i]
            i = i + 1

        else

            result[#result + 1] = right[j]
            j = j + 1

        end

    end

    while i <= #left do

        result[#result + 1] = left[i]
        i = i + 1

    end

    while j <= #right do

        result[#result + 1] = right[j]
        j = j + 1

    end

    return result

end

local words = {"lua", "python", "c", "java", "ruby"}
local sorted = mergeSort(words)

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

Lua compares strings naturally, so Merge Sort does not need special changes. This example helps beginners see that the same algorithm can handle different data types easily.

Program 7: Merge Sort with Duplicate Values

This program shows that Merge Sort handles duplicate values correctly.

local numbers = {4, 2, 4, 1, 2, 3}

local function mergeSort(arr)

    if #arr <= 1 then
        return arr
    end

    local mid = math.floor(#arr / 2)
    local left = mergeSort({table.unpack(arr, 1, mid)})
    local right = mergeSort({table.unpack(arr, mid + 1)})

    local result = {}
    local i, j = 1, 1

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

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

            result[#result + 1] = left[i]
            i = i + 1

        else

            result[#result + 1] = right[j]
            j = j + 1

        end

    end

    while i <= #left do

        result[#result + 1] = left[i]
        i = i + 1

    end

    while j <= #right do

        result[#result + 1] = right[j]
        j = j + 1

    end

    return result

end

local sorted = mergeSort(numbers)

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

This reassures beginners that Merge Sort is stable and reliable. Duplicate values remain correctly grouped after sorting, which is important in many real applications.

Program 8: Merge Sort as a Utility Function

This version emphasizes reusability and clean structure for real projects.

local function mergeSort(arr)

    if #arr <= 1 then
        return arr
    end

    local mid = math.floor(#arr / 2)
    local left = {}
    local right = {}

    for i = 1, mid do
        left[i] = arr[i]
    end

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

    left = mergeSort(left)
    right = mergeSort(right)

    local result = {}
    local i, j = 1, 1

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

        if left[i] < right[j] then

            result[#result + 1] = left[i]
            i = i + 1

        else

            result[#result + 1] = right[j]
            j = j + 1

        end

    end

    while i <= #left do

        result[#result + 1] = left[i]
        i = i + 1

    end

    while j <= #right do

        result[#result + 1] = right[j]
        j = j + 1

    end

    return result

end

local numbers = {21, 10, 12, 20, 25, 13}
local sorted = mergeSort(numbers)

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

This style is close to what you would use in a real Lua project. It helps beginners learn how to write maintainable and reusable code.

Program 9: Merge Sort with Negative and Floating Point Numbers

Merge Sort naturally supports negative and floating point numbers. This program clearly demonstrates that behavior.

local numbers = {3.5, -2.1, 4.8, 0, -6.3}

local function mergeSort(arr)

    if #arr <= 1 then
        return arr
    end

    local mid = math.floor(#arr / 2)
    local left = mergeSort({table.unpack(arr, 1, mid)})
    local right = mergeSort({table.unpack(arr, mid + 1)})

    local result = {}
    local i, j = 1, 1

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

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

            result[#result + 1] = left[i]
            i = i + 1

        else

            result[#result + 1] = right[j]
            j = j + 1

        end

    end

    while i <= #left do

        result[#result + 1] = left[i]
        i = i + 1

    end

    while j <= #right do

        result[#result + 1] = right[j]
        j = j + 1

    end

    return result

end

local sorted = mergeSort(numbers)

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

Lua compares numbers naturally, so Merge Sort works without any special changes. This confirms that the algorithm is suitable for real-world numeric data.

Frequently Asked Questions (FAQ)

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

Q1. Why is Merge Sort faster than simple sorting algorithms?
Merge Sort divides the data into smaller parts and sorts them efficiently, which makes it much faster for large data sets.

Q2. Does Merge Sort use more memory?
Yes, Merge Sort usually uses extra memory because it creates temporary tables during merging.

Q3. Is Merge Sort stable?
Yes, Merge Sort keeps equal values in their original order, which makes it stable.

Q4. Does Lua have a built-in sorting function?
Lua provides table.sort, but learning Merge Sort helps you understand how advanced sorting works internally.

Conclusion

Merge Sort is a powerful and efficient sorting algorithm that every Lua programmer should understand. In this article, you explored many Lua programs that implement Merge Sort using recursion, iteration, reusable functions, and different data types. You also saw how it handles strings, duplicate values, negative numbers, and floating point values.

Although Merge Sort may feel complex at first, practice makes it easier. Try modifying the examples, adding print statements, or sorting different kinds of data. With time and hands-on experience, Merge Sort will become a valuable tool in your Lua programming journey.

Scroll to Top