3way Merge Sort (original) (raw)

3-way Merge Sort

Last Updated : 23 Jul, 2025

Merge Sort is a divide-and-conquer algorithm that recursively splits an array into two halves, sorts each half, and then merges them. A variation of this is **3-way Merge Sort, where instead of splitting the array into two parts, we divide it into **three equal parts.

In traditional Merge Sort, the array is recursively divided into halves until we reach subarrays of size **1. In **3-way Merge Sort, the array is recursively divided into **three parts, reducing the depth of recursion and potentially improving efficiency.

**Examples:

**Input: arr = [45, -2, -45, 78, 30, -42, 10, 19, 73, 93]
**Output: [-45, -42, -2, 10, 19, 30, 45, 73, 78, 93]

**Input: arr = [23, -19]
**Output: [-19, 23]

Approach:

The idea is to extend merge sort by dividing the array into three parts instead of two. First, recursively sort the three subarrays. Then, merge them by selecting the smallest element among the three at each step. Temporary arrays store the divided parts, and a comparison process finds the minimum to insert into the original array.

**Steps to implement the above idea:

// C++ program to implement 3-way Merge Sort #include <bits/stdc++.h> using namespace std;

void merge(int arr[], int left, int mid1, int mid2, int right) {

// Sizes of three subarrays
int size1 = mid1 - left + 1;
int size2 = mid2 - mid1;
int size3 = right - mid2;

// Temporary arrays for three parts
vector<int> leftArr(size1), midArr(size2), rightArr(size3);

// Copy data to temporary arrays
for (int i = 0; i < size1; i++) {
    leftArr[i] = arr[left + i];
}
for (int i = 0; i < size2; i++) {
    midArr[i] = arr[mid1 + 1 + i];
}
for (int i = 0; i < size3; i++) {
    rightArr[i] = arr[mid2 + 1 + i];
}

// Merge three sorted subarrays
int i = 0, j = 0, k = 0, index = left;
while (i < size1 || j < size2 || k < size3) {
    int minValue = INT_MAX, minIdx = -1;

    // Find the smallest among the three current elements
    if (i < size1 && leftArr[i] < minValue) {
        minValue = leftArr[i];
        minIdx = 0;
    }
    if (j < size2 && midArr[j] < minValue) {
        minValue = midArr[j];
        minIdx = 1;
    }
    if (k < size3 && rightArr[k] < minValue) {
        minValue = rightArr[k];
        minIdx = 2;
    }

    // Place the smallest element in the merged array
    if (minIdx == 0) {
        arr[index++] = leftArr[i++];
    } else if (minIdx == 1) {
        arr[index++] = midArr[j++];
    } else {
        arr[index++] = rightArr[k++];
    }
}

}

void threeWayMergeSort(int arr[], int left, int right) {

// Base case: If single element, return
if (left >= right) {
    return;
}

// Finding two midpoints for 3-way split
int mid1 = left + (right - left) / 3;
int mid2 = left + 2 * (right - left) / 3;

// Recursively sort first third
threeWayMergeSort(arr, left, mid1);

// Recursively sort second third
threeWayMergeSort(arr, mid1 + 1, mid2);

// Recursively sort last third
threeWayMergeSort(arr, mid2 + 1, right);

// Merge the sorted parts
merge(arr, left, mid1, mid2, right);

}

int main() {

// Input array
int arr[] = {5, 2, 9, 1, 6, 3, 8, 4, 7};

// Size of the array
int n = sizeof(arr) / sizeof(arr[0]);

// Calling 3-way merge sort function
threeWayMergeSort(arr, 0, n - 1);

// Printing the sorted array
for (int i = 0; i < n; i++) {
    cout << arr[i] << " ";
}

return 0;

}

C

// C program to implement 3-way Merge Sort #include <stdio.h> #include <limits.h> #include <stdlib.h>

void merge(int arr[], int left, int mid1, int mid2, int right) {

// Sizes of three subarrays
int size1 = mid1 - left + 1;
int size2 = mid2 - mid1;
int size3 = right - mid2;

// Temporary arrays for three parts
int *leftArr = (int *)malloc(size1 * sizeof(int));
int *midArr = (int *)malloc(size2 * sizeof(int));
int *rightArr = (int *)malloc(size3 * sizeof(int));

// Copy data to temporary arrays
for (int i = 0; i < size1; i++) {
    leftArr[i] = arr[left + i];
}
for (int i = 0; i < size2; i++) {
    midArr[i] = arr[mid1 + 1 + i];
}
for (int i = 0; i < size3; i++) {
    rightArr[i] = arr[mid2 + 1 + i];
}

// Merge three sorted subarrays
int i = 0, j = 0, k = 0, index = left;
while (i < size1 || j < size2 || k < size3) {
    int minValue = INT_MAX, minIdx = -1;
    
    // Find the smallest among the three current elements
    if (i < size1 && leftArr[i] < minValue) {
        minValue = leftArr[i];
        minIdx = 0;
    }
    if (j < size2 && midArr[j] < minValue) {
        minValue = midArr[j];
        minIdx = 1;
    }
    if (k < size3 && rightArr[k] < minValue) {
        minValue = rightArr[k];
        minIdx = 2;
    }
    
    // Place the smallest element in the merged array
    if (minIdx == 0) {
        arr[index++] = leftArr[i++];
    } else if (minIdx == 1) {
        arr[index++] = midArr[j++];
    } else {
        arr[index++] = rightArr[k++];
    }
}

free(leftArr);
free(midArr);
free(rightArr);

}

void threeWayMergeSort(int arr[], int left, int right) {

// Base case: If single element, return
if (left >= right) {
    return;
}

// Finding two midpoints for 3-way split
int mid1 = left + (right - left) / 3;
int mid2 = left + 2 * (right - left) / 3;

// Recursively sort first third
threeWayMergeSort(arr, left, mid1);

// Recursively sort second third
threeWayMergeSort(arr, mid1 + 1, mid2);

// Recursively sort last third
threeWayMergeSort(arr, mid2 + 1, right);

// Merge the sorted parts
merge(arr, left, mid1, mid2, right);

}

int main() {

// Input array
int arr[] = {5, 2, 9, 1, 6, 3, 8, 4, 7};

// Size of the array
int n = sizeof(arr) / sizeof(arr[0]);

// Calling 3-way merge sort function
threeWayMergeSort(arr, 0, n - 1);

// Printing the sorted array
for (int i = 0; i < n; i++) {
    printf("%d ", arr[i]);
}

return 0;

}

Java

// Java program to implement 3-way Merge Sort import java.util.*;

class GfG {

static void merge(int arr[], int left, int mid1, int mid2, int right) {
    
    // Sizes of three subarrays
    int size1 = mid1 - left + 1;
    int size2 = mid2 - mid1;
    int size3 = right - mid2;
    
    // Temporary arrays for three parts
    int[] leftArr = new int[size1];
    int[] midArr = new int[size2];
    int[] rightArr = new int[size3];
    
    // Copy data to temporary arrays
    for (int i = 0; i < size1; i++) {
        leftArr[i] = arr[left + i];
    }
    for (int i = 0; i < size2; i++) {
        midArr[i] = arr[mid1 + 1 + i];
    }
    for (int i = 0; i < size3; i++) {
        rightArr[i] = arr[mid2 + 1 + i];
    }
    
    // Merge three sorted subarrays
    int i = 0, j = 0, k = 0, index = left;
    while (i < size1 || j < size2 || k < size3) {
        int minValue = Integer.MAX_VALUE, minIdx = -1;
        
        // Find the smallest among the three current elements
        if (i < size1 && leftArr[i] < minValue) {
            minValue = leftArr[i];
            minIdx = 0;
        }
        if (j < size2 && midArr[j] < minValue) {
            minValue = midArr[j];
            minIdx = 1;
        }
        if (k < size3 && rightArr[k] < minValue) {
            minValue = rightArr[k];
            minIdx = 2;
        }
        
        // Place the smallest element in the merged array
        if (minIdx == 0) {
            arr[index++] = leftArr[i++];
        } else if (minIdx == 1) {
            arr[index++] = midArr[j++];
        } else {
            arr[index++] = rightArr[k++];
        }
    }
}

static void threeWayMergeSort(int arr[], int left, int right) {
    
    // Base case: If single element, return
    if (left >= right) {
        return;
    }
    
    // Finding two midpoints for 3-way split
    int mid1 = left + (right - left) / 3;
    int mid2 = left + 2 * (right - left) / 3;
    
    // Recursively sort first third
    threeWayMergeSort(arr, left, mid1);
    
    // Recursively sort second third
    threeWayMergeSort(arr, mid1 + 1, mid2);
    
    // Recursively sort last third
    threeWayMergeSort(arr, mid2 + 1, right);
    
    // Merge the sorted parts
    merge(arr, left, mid1, mid2, right);
}

public static void main(String args[]) {
    
    // Input array
    int arr[] = {5, 2, 9, 1, 6, 3, 8, 4, 7};
    
    // Size of the array
    int n = arr.length;
    
    // Calling 3-way merge sort function
    threeWayMergeSort(arr, 0, n - 1);
    
    // Printing the sorted array
    for (int i = 0; i < n; i++) {
        System.out.print(arr[i] + " ");
    }
}

}

Python

Python program to implement 3-way Merge Sort

def merge(arr, left, mid1, mid2, right):

# Sizes of three subarrays
size1 = mid1 - left + 1
size2 = mid2 - mid1
size3 = right - mid2

# Temporary arrays for three parts
left_arr = arr[left:left + size1]
mid_arr = arr[mid1 + 1:mid1 + 1 + size2]
right_arr = arr[mid2 + 1:mid2 + 1 + size3]

# Merge three sorted subarrays
i = j = k = 0
index = left

while i < size1 or j < size2 or k < size3:
    min_value = float('inf')
    min_idx = -1
    
    # Find the smallest among the three current elements
    if i < size1 and left_arr[i] < min_value:
        min_value = left_arr[i]
        min_idx = 0
    if j < size2 and mid_arr[j] < min_value:
        min_value = mid_arr[j]
        min_idx = 1
    if k < size3 and right_arr[k] < min_value:
        min_value = right_arr[k]
        min_idx = 2
    
    # Place the smallest element in the merged array
    if min_idx == 0:
        arr[index] = left_arr[i]
        i += 1
    elif min_idx == 1:
        arr[index] = mid_arr[j]
        j += 1
    else:
        arr[index] = right_arr[k]
        k += 1
    
    index += 1

def three_way_merge_sort(arr, left, right):

# Base case: If single element, return
if left >= right:
    return

# Finding two midpoints for 3-way split
mid1 = left + (right - left) // 3
mid2 = left + 2 * (right - left) // 3

# Recursively sort first third
three_way_merge_sort(arr, left, mid1)

# Recursively sort second third
three_way_merge_sort(arr, mid1 + 1, mid2)

# Recursively sort last third
three_way_merge_sort(arr, mid2 + 1, right)

# Merge the sorted parts
merge(arr, left, mid1, mid2, right)

if name == "main":

# Input array
arr = [5, 2, 9, 1, 6, 3, 8, 4, 7]

# Calling 3-way merge sort function
three_way_merge_sort(arr, 0, len(arr) - 1)

# Printing the sorted array
print(*arr)

C#

// C# program to implement 3-way Merge Sort

using System;

class GfG {

// Function to merge three sorted subarrays
static void Merge(int[] arr, int left, int mid1, int mid2, int right) {
    
    // Sizes of three subarrays
    int size1 = mid1 - left + 1;
    int size2 = mid2 - mid1;
    int size3 = right - mid2;

    // Temporary arrays for three parts
    int[] leftArr = new int[size1];
    int[] midArr = new int[size2];
    int[] rightArr = new int[size3];

    // Copy data to temporary arrays
    for (int i = 0; i < size1; i++) {
        leftArr[i] = arr[left + i];
    }
    for (int i = 0; i < size2; i++) {
        midArr[i] = arr[mid1 + 1 + i];
    }
    for (int i = 0; i < size3; i++) {
        rightArr[i] = arr[mid2 + 1 + i];
    }

    // Merge three sorted subarrays
    int i1 = 0, i2 = 0, i3 = 0, index = left;
    while (i1 < size1 || i2 < size2 || i3 < size3) {
        int minValue = int.MaxValue, minIdx = -1;

        // Find the smallest among the three current elements
        if (i1 < size1 && leftArr[i1] < minValue) {
            minValue = leftArr[i1];
            minIdx = 0;
        }
        if (i2 < size2 && midArr[i2] < minValue) {
            minValue = midArr[i2];
            minIdx = 1;
        }
        if (i3 < size3 && rightArr[i3] < minValue) {
            minValue = rightArr[i3];
            minIdx = 2;
        }

        // Place the smallest element in the merged array
        if (minIdx == 0) {
            arr[index++] = leftArr[i1++];
        } else if (minIdx == 1) {
            arr[index++] = midArr[i2++];
        } else {
            arr[index++] = rightArr[i3++];
        }
    }
}

// Function to perform 3-way merge sort
static void ThreeWayMergeSort(int[] arr, int left, int right) {
    
    // Base case: If single element, return
    if (left >= right) {
        return;
    }

    // Finding two midpoints for 3-way split
    int mid1 = left + (right - left) / 3;
    int mid2 = left + 2 * (right - left) / 3;

    // Recursively sort first third
    ThreeWayMergeSort(arr, left, mid1);
    
    // Recursively sort second third
    ThreeWayMergeSort(arr, mid1 + 1, mid2);
    
    // Recursively sort last third
    ThreeWayMergeSort(arr, mid2 + 1, right);

    // Merge the sorted parts
    Merge(arr, left, mid1, mid2, right);
}

// Driver method
public static void Main() {
    
    // Input array
    int[] arr = {5, 2, 9, 1, 6, 3, 8, 4, 7};
    
    // Size of the array
    int n = arr.Length;
    
    // Calling 3-way merge sort function
    ThreeWayMergeSort(arr, 0, n - 1);
    
    // Printing the sorted array
    foreach (int num in arr) {
        Console.Write(num + " ");
    }
}

}

JavaScript

// Javascript program to implement 3-way Merge Sort

function merge(arr, left, mid1, mid2, right) {

// Sizes of three subarrays
let size1 = mid1 - left + 1;
let size2 = mid2 - mid1;
let size3 = right - mid2;

// Temporary arrays for three parts
let leftArr = arr.slice(left, left + size1);
let midArr = arr.slice(mid1 + 1, mid1 + 1 + size2);
let rightArr = arr.slice(mid2 + 1, mid2 + 1 + size3);

// Merge three sorted subarrays
let i = 0, j = 0, k = 0, index = left;

while (i < size1 || j < size2 || k < size3) {
    let minValue = Infinity;
    let minIdx = -1;
    
    // Find the smallest among the three current elements
    if (i < size1 && leftArr[i] < minValue) {
        minValue = leftArr[i];
        minIdx = 0;
    }
    if (j < size2 && midArr[j] < minValue) {
        minValue = midArr[j];
        minIdx = 1;
    }
    if (k < size3 && rightArr[k] < minValue) {
        minValue = rightArr[k];
        minIdx = 2;
    }
    
    // Place the smallest element in the merged array
    if (minIdx === 0) {
        arr[index] = leftArr[i++];
    } else if (minIdx === 1) {
        arr[index] = midArr[j++];
    } else {
        arr[index] = rightArr[k++];
    }
    
    index++;
}

}

function threeWayMergeSort(arr, left, right) {

// Base case: If single element, return
if (left >= right) {
    return;
}

// Finding two midpoints for 3-way split
let mid1 = left + Math.floor((right - left) / 3);
let mid2 = left + 2 * Math.floor((right - left) / 3);

// Recursively sort first third
threeWayMergeSort(arr, left, mid1);

// Recursively sort second third
threeWayMergeSort(arr, mid1 + 1, mid2);

// Recursively sort last third
threeWayMergeSort(arr, mid2 + 1, right);

// Merge the sorted parts
merge(arr, left, mid1, mid2, right);

}

// Input array let arr = [5, 2, 9, 1, 6, 3, 8, 4, 7];

// Calling 3-way merge sort function threeWayMergeSort(arr, 0, arr.length - 1);

// Printing the sorted array console.log(...arr);

`

**Time Complexity: **O(n log₃ n), because the array is divided into three parts at each level, and merging takes **O(n) time per level, leading to a recurrence of **T(n) = 3T(n/3) + O(n).
**Auxiliary Space: **O(n) due to the use of temporary arrays for storing the three subarrays during merging.

**Similar article: 3 way Quick Sort