TimSort

TimSort is a sorting algorithm based on Insertion Sort and Merge Sort.

  1. A stable sorting algorithm works in O(n Log n) time
  2. Used in Java’s Arrays.sort() as well as Python’s sorted() and sort().
  3. First sort small pieces using Insertion Sort, then merges the pieces using merge of merge sort.

We divide the Array into blocks known as Run. We sort those runs using insertion sort one by one and then merge those runs using combine function used in merge sort. If the size of Array is less than run, then Array get sorted just by using Insertion Sort. The size of run may vary from 32 to 64 depending upon the size of the array. Note that merge function performs well when sizes subarrays are powers of 2. The idea is based on the fact that insertion sort performs well for small arrays.



Details of below implementation :

  • We consider size of run as 32.
  • We one by one sort pieces of size equal to run
  • After sorting individual pieces, we merge them one by one. We double the size of merged subarrays after every iteration.

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program to perform TimSort.
#include<bits/stdc++.h>
using namespace std;
const int RUN = 32;
  
// this function sorts array from left index to
// to right index which is of size atmost RUN
void insertionSort(int arr[], int left, int right)
{
    for (int i = left + 1; i <= right; i++)
    {
        int temp = arr[i];
        int j = i - 1;
        while (arr[j] > temp && j >= left)
        {
            arr[j+1] = arr[j];
            j--;
        }
        arr[j+1] = temp;
    }
}
  
// merge function merges the sorted runs
void merge(int arr[], int l, int m, int r)
{
    // original array is broken in two parts
    // left and right array
    int len1 = m - l + 1, len2 = r - m;
    int left[len1], right[len2];
    for (int i = 0; i < len1; i++)
        left[i] = arr[l + i];
    for (int i = 0; i < len2; i++)
        right[i] = arr[m + 1 + i];
  
    int i = 0;
    int j = 0;
    int k = l;
  
    // after comparing, we merge those two array
    // in larger sub array
    while (i < len1 && j < len2)
    {
        if (left[i] <= right[j])
        {
            arr[k] = left[i];
            i++;
        }
        else
        {
            arr[k] = right[j];
            j++;
        }
        k++;
    }
  
    // copy remaining elements of left, if any
    while (i < len1)
    {
        arr[k] = left[i];
        k++;
        i++;
    }
  
    // copy remaining element of right, if any
    while (j < len2)
    {
        arr[k] = right[j];
        k++;
        j++;
    }
}
  
// iterative Timsort function to sort the
// array[0...n-1] (similar to merge sort)
void timSort(int arr[], int n)
{
    // Sort individual subarrays of size RUN
    for (int i = 0; i < n; i+=RUN)
        insertionSort(arr, i, min((i+31), (n-1)));
  
    // start merging from size RUN (or 32). It will merge
    // to form size 64, then 128, 256 and so on ....
    for (int size = RUN; size < n; size = 2*size)
    {
        // pick starting point of left sub array. We
        // are going to merge arr[left..left+size-1]
        // and arr[left+size, left+2*size-1]
        // After every merge, we increase left by 2*size
        for (int left = 0; left < n; left += 2*size)
        {
            // find ending point of left sub array
            // mid+1 is starting point of right sub array
            int mid = left + size - 1;
            int right = min((left + 2*size - 1), (n-1));
  
            // merge sub array arr[left.....mid] &
            // arr[mid+1....right]
            merge(arr, left, mid, right);
        }
    }
}
  
// utility function to print the Array
void printArray(int arr[], int n)
{
    for (int i = 0; i < n; i++)
        printf("%d  ", arr[i]);
    printf("\n");
}
  
// Driver program to test above function
int main()
{
    int arr[] = {5, 21, 7, 23, 19};
    int n = sizeof(arr)/sizeof(arr[0]);
    printf("Given Array is\n");
    printArray(arr, n);
  
    timSort(arr, n);
  
    printf("After Sorting Array is\n");
    printArray(arr, n);
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program to perform TimSort. 
class GFG 
{
  
    static int RUN = 32;
  
    // this function sorts array from left index to 
    // to right index which is of size atmost RUN 
    public static void insertionSort(int[] arr, int left, int right) 
    {
        for (int i = left + 1; i <= right; i++) 
        {
            int temp = arr[i];
            int j = i - 1;
            while (arr[j] > temp && j >= left)
            {
                arr[j + 1] = arr[j];
                j--;
            }
            arr[j + 1] = temp;
        }
    }
  
    // merge function merges the sorted runs 
    public static void merge(int[] arr, int l, 
                                int m, int r)
    {
        // original array is broken in two parts 
        // left and right array 
        int len1 = m - l + 1, len2 = r - m;
        int[] left = new int[len1];
        int[] right = new int[len2];
        for (int x = 0; x < len1; x++) 
        {
            left[x] = arr[l + x];
        }
        for (int x = 0; x < len2; x++) 
        {
            right[x] = arr[m + 1 + x];
        }
  
        int i = 0;
        int j = 0;
        int k = l;
  
        // after comparing, we merge those two array 
        // in larger sub array 
        while (i < len1 && j < len2) 
        {
            if (left[i] <= right[j]) 
            {
                arr[k] = left[i];
                i++;
            }
            else 
            {
                arr[k] = right[j];
                j++;
            }
            k++;
        }
  
        // copy remaining elements of left, if any 
        while (i < len1)
        {
            arr[k] = left[i];
            k++;
            i++;
        }
  
        // copy remaining element of right, if any 
        while (j < len2) 
        {
            arr[k] = right[j];
            k++;
            j++;
        }
    }
  
    // iterative Timsort function to sort the 
    // array[0...n-1] (similar to merge sort) 
    public static void timSort(int[] arr, int n) 
    {
          
        // Sort individual subarrays of size RUN 
        for (int i = 0; i < n; i += RUN) 
        {
            insertionSort(arr, i, Math.min((i + 31), (n - 1)));
        }
  
        // start merging from size RUN (or 32). It will merge 
        // to form size 64, then 128, 256 and so on .... 
        for (int size = RUN; size < n; size = 2 * size) 
        {
              
            // pick starting point of left sub array. We 
            // are going to merge arr[left..left+size-1] 
            // and arr[left+size, left+2*size-1] 
            // After every merge, we increase left by 2*size 
            for (int left = 0; left < n; left += 2 * size) 
            {
                  
                // find ending point of left sub array 
                // mid+1 is starting point of right sub array 
                int mid = left + size - 1;
                int right = Math.min((left + 2 * size - 1), (n - 1));
  
                // merge sub array arr[left.....mid] & 
                // arr[mid+1....right] 
                merge(arr, left, mid, right);
            }
        }
    }
  
    // utility function to print the Array 
    public static void printArray(int[] arr, int n)
    {
        for (int i = 0; i < n; i++)
        {
            System.out.print(arr[i] + " ");
        }
        System.out.print("\n");
    }
  
    // Driver code 
    public static void main(String[] args) 
    {
        int[] arr = {5, 21, 7, 23, 19};
        int n = arr.length;
        System.out.print("Given Array is\n");
        printArray(arr, n);
  
        timSort(arr, n);
  
        System.out.print("After Sorting Array is\n");
        printArray(arr, n);
    }
}
  
// This code has been contributed by 29AjayKumar

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 program to perform TimSort. 
RUN = 32 
    
# This function sorts array from left index to 
# to right index which is of size atmost RUN 
def insertionSort(arr, left, right): 
   
    for i in range(left + 1, right+1): 
       
        temp = arr[i] 
        j = i - 1 
        while arr[j] > temp and j >= left: 
           
            arr[j+1] = arr[j] 
            j -= 1
           
        arr[j+1] = temp 
    
# merge function merges the sorted runs 
def merge(arr, l, m, r):
   
    # original array is broken in two parts 
    # left and right array 
    len1, len2 =  m - l + 1, r -
    left, right = [], [] 
    for i in range(0, len1): 
        left.append(arr[l + i]) 
    for i in range(0, len2): 
        right.append(arr[m + 1 + i]) 
    
    i, j, k = 0, 0, l
    # after comparing, we merge those two array 
    # in larger sub array 
    while i < len1 and j < len2: 
       
        if left[i] <= right[j]: 
            arr[k] = left[i] 
            i += 1 
           
        else:
            arr[k] = right[j] 
            j += 1 
           
        k += 1
       
    # copy remaining elements of left, if any 
    while i < len1: 
       
        arr[k] = left[i] 
        k += 1 
        i += 1
    
    # copy remaining element of right, if any 
    while j < len2: 
        arr[k] = right[j] 
        k += 1
        j += 1
      
# iterative Timsort function to sort the 
# array[0...n-1] (similar to merge sort) 
def timSort(arr, n): 
   
    # Sort individual subarrays of size RUN 
    for i in range(0, n, RUN): 
        insertionSort(arr, i, min((i+31), (n-1))) 
    
    # start merging from size RUN (or 32). It will merge 
    # to form size 64, then 128, 256 and so on .... 
    size = RUN
    while size < n: 
       
        # pick starting point of left sub array. We 
        # are going to merge arr[left..left+size-1] 
        # and arr[left+size, left+2*size-1] 
        # After every merge, we increase left by 2*size 
        for left in range(0, n, 2*size): 
           
            # find ending point of left sub array 
            # mid+1 is starting point of right sub array 
            mid = left + size - 1 
            right = min((left + 2*size - 1), (n-1)) 
    
            # merge sub array arr[left.....mid] & 
            # arr[mid+1....right] 
            merge(arr, left, mid, right) 
          
        size = 2*size
           
# utility function to print the Array 
def printArray(arr, n): 
   
    for i in range(0, n): 
        print(arr[i], end = " "
    print() 
   
    
# Driver program to test above function 
if __name__ == "__main__":
   
    arr = [5, 21, 7, 23, 19
    n = len(arr) 
    print("Given Array is"
    printArray(arr, n) 
    
    timSort(arr, n) 
    
    print("After Sorting Array is"
    printArray(arr, n) 
      
# This code is contributed by Rituraj Jain

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# program to perform TimSort. 
using System; 
   
class GFG 
    public const int RUN = 32;
      
    // this function sorts array from left index to 
    // to right index which is of size atmost RUN 
    public static void insertionSort(int[] arr, int left, int right) 
    
        for (int i = left + 1; i <= right; i++) 
        
            int temp = arr[i]; 
            int j = i - 1; 
            while (arr[j] > temp && j >= left) 
            
                arr[j+1] = arr[j]; 
                j--; 
            
            arr[j+1] = temp; 
        
    
        
    // merge function merges the sorted runs 
    public static void merge(int[] arr, int l, int m, int r) 
    
        // original array is broken in two parts 
        // left and right array 
        int len1 = m - l + 1, len2 = r - m; 
        int[] left = new int[len1];
        int[] right = new int[len2]; 
        for (int x = 0; x < len1; x++)
            left[x] = arr[l + x]; 
        for (int x = 0; x < len2; x++) 
            right[x] = arr[m + 1 + x]; 
        
        int i = 0; 
        int j = 0; 
        int k = l; 
        
        // after comparing, we merge those two array 
        // in larger sub array 
        while (i < len1 && j < len2) 
        
            if (left[i] <= right[j]) 
            
                arr[k] = left[i]; 
                i++; 
            
            else
            
                arr[k] = right[j]; 
                j++; 
            
            k++; 
        
        
        // copy remaining elements of left, if any 
        while (i < len1) 
        
            arr[k] = left[i]; 
            k++; 
            i++; 
        
        
        // copy remaining element of right, if any 
        while (j < len2) 
        
            arr[k] = right[j]; 
            k++; 
            j++; 
        
    
        
    // iterative Timsort function to sort the 
    // array[0...n-1] (similar to merge sort) 
    public static void timSort(int[] arr, int n) 
    
        // Sort individual subarrays of size RUN 
        for (int i = 0; i < n; i+=RUN) 
            insertionSort(arr, i, Math.Min((i+31), (n-1))); 
        
        // start merging from size RUN (or 32). It will merge 
        // to form size 64, then 128, 256 and so on .... 
        for (int size = RUN; size < n; size = 2*size) 
        
            // pick starting point of left sub array. We 
            // are going to merge arr[left..left+size-1] 
            // and arr[left+size, left+2*size-1] 
            // After every merge, we increase left by 2*size 
            for (int left = 0; left < n; left += 2*size) 
            
                // find ending point of left sub array 
                // mid+1 is starting point of right sub array 
                int mid = left + size - 1; 
                int right = Math.Min((left + 2*size - 1), (n-1)); 
        
                // merge sub array arr[left.....mid] & 
                // arr[mid+1....right] 
                merge(arr, left, mid, right); 
            
        
    
        
    // utility function to print the Array 
    public static void printArray(int[] arr, int n) 
    
        for (int i = 0; i < n; i++) 
            Console.Write(arr[i] + " "); 
        Console.Write("\n"); 
    
        
    // Driver program to test above function
      
    public static void Main()
    {
        int[] arr = {5, 21, 7, 23, 19}; 
        int n = arr.Length;
        Console.Write("Given Array is\n"); 
        printArray(arr, n); 
        
        timSort(arr, n); 
        
        Console.Write("After Sorting Array is\n"); 
        printArray(arr, n); 
    }
      
    //This code is contributed by DrRoot_
}

chevron_right


Output:

Given Array is
5  21  7  23  19
After Sorting Array is
5  7  19  21  23

References :
https://svn.python.org/projects/python/trunk/Objects/listsort.txt
https://en.wikipedia.org/wiki/Timsort#Minimum_size_.28minrun.29

This article is contributed by Aditya Kumar. If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.



My Personal Notes arrow_drop_up



Article Tags :
Practice Tags :


Be the First to upvote.


Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.