Tim Sort Algorithm in C++

C++Server Side ProgrammingProgramming

The Timsort is a stable sorting algorithm that uses the idea of merge sort and insertion sort. It can also be called as a hybrid algorithm of insertion and merge sort. It is widely used in Java, Python, C, and C++ inbuilt sort algorithms. The idea behind this algorithm is to sort small chunks using insertion sort and then merge all the big chunks using the merge function of the merge sort algorithm.

Working

In this algorithm, the array is divided into small chunks. The chunks are known as RUN. Each RUN is taken and sorted using the insertion sort technique. After all the RUN are sorted these are merged using the merge function.

There may be a case where the size of the array can be less than RUN. In such a case, the array is sorted by the insertion sort technique. Usually, the RUN chunk varies from 32 to 64 depending on the size of the array. The merge function will only merge if the subarray chunk has the size of powers of 2.

The advantage of using insertion sort is because insertion sort works fine for the array with a small size.

Time complexity

  • Best case - Omega(n)

  • Average case - O(nlogn)

  • Worst case - O(nlogn)

Algorithms of Tim Sort

  • Initialize a RUN with the size of 32.

  • Implement Insertion sort for RUN size chunks.

  • A function merge(int arr[], int l, int m, int r) takes an array, left elements, middle of the array and right elements of the array as input. The function returns the merged sorted chunks of size 32.

  • Initialize length of the array having all the left elements and the length of the array having all the right elements.

  • After filling the left array and right array, Iterate over the left array as well as right array.

  • If the element in the left array is less than the element in the right array, push the element into a larger array.

  • Otherwise push the element into a smaller array accordingly.

  • Copy the remaining element in the left array and right array into a larger array.

  • A function timSortAlgo(int arr[], int n) takes an array and its size as input. Which calls the insertion Sort initially and merges the array elements.

  • Return the output as the final elements of the array using Tim Sort.

Example (C++)

#include<bits/stdc++.h>
using namespace std;
const int RUN = 32; // Initialising the RUN to get chunks
void insertionSort(int arr[], int left, int right) // Implementing insertion
sort for RUN size chunks{
   for (int i = left + 1; i <= right; i++){
      int t = arr[i];
      int j = i - 1;
      while (j >= left && t < arr[j]){
         arr[j+1] = arr[j--];
      }
      arr[j+1] = t;
   }
}
void merge(int arr[], int l, int m, int r) // using the merge function the
sorted chunks of size 32 are merged into one{
   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]; // Filling left array
   for (int i = 0; i < len2; i++)
      right[i] = arr[m + 1 + i]; // Filling right array
   int i = 0;
   int j = 0;
   int k = l;
   while (i < len1 && j < len2) // Iterate into both arrays left and right{
      if (left[i] <= right[j]) // IF element in left is less then increment i by pushing into larger array{
         arr[k] = left[i];
         i++;
      } else {
         arr[k] = right[j]; // Element in right array is greater
         increment j
         j++;
      }
      k++;
   }
   while (i < len1) // This loop copies remaining element in left array{
      arr[k] = left[i];
      k++;
      i++;
   }
   while (j < len2) // This loop copies remaining element in right array{
      arr[k] = right[j];
      k++;
      j++;
   }
}
void timSortAlgo(int arr[], int n){
   for (int i = 0; i < n; i+=RUN) insertionSort(arr, i, min((i+31), (n-1))); //Call insertionSort()
   for (int s = RUN; s < n; s = 2*s) // Start merging from size RUN (or 32). It will continue upto 2*RUN{
      // 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*s){
         int mid = left + s - 1; // find ending point of left sub
         array mid+1 is starting point of right sub array
         int right = min((left + 2*s - 1), (n-1));
         merge(arr, left, mid, right); // merge sub array
         arr[left.....mid] & arr[mid+1....right]
      }
   }
}
void printArray(int arr[], int n){
   for (int i = 0; i < n; i++)
      cout << arr[i] << " ";
   cout << endl;
}
// Main function to implement timsort algorithm
int main(){
   int arr[] = {-2, 7, 15, -14, 0, 15, 0, 7, -7, -4, -13, 5, 8, -14, 12};
   int n = sizeof(arr)/sizeof(arr[0]);
   cout << "The Original array- ";
   printArray(arr, n);
   // calling the timsortAlgo function to sort array
   timSortAlgo(arr, n);
   cout<<"After Sorting Array Using TimSort Algorithm- ";
   printArray(arr, n); // Calling print function
   return 0;
}
raja
Published on 05-Feb-2021 10:58:26
Advertisements