-
Notifications
You must be signed in to change notification settings - Fork 0
Home
Tim-sort is a sorting algorithm derived from insertion sort and merge sort. It was designed to perform optimally on different kind of real-world data. Tim sort is an adaptive sorting algorithm that needs O(n log n) comparisons to sort an array of n elements. It was designed and implemented by Tim Peters in 2002 in a python programming language. It has been python's standard sorting algorithm since version 2.3. It is the fastest sorting algorithm. The basic approach used in the Tim sort algorithm is - first sort small chunks by using the insertion sort and then merge all the big chunks using the merge function of the merge sort. Now, let's see the algorithm of Tim sort.
Step 1 - Divide the array into the number of blocks known as run.
Step 2 - Consider the size of run, either 32 or 64.
Step 3 - Sort the individual elements of every run one by one using insertion sort.
Step 4 - Merge the sorted runs one by one using the merge function of merge sort.
Step 5 - Double the size of merged sub-arrays after every iteration.
In Tim sort, first the array is divided into small chunks that are known as RUN. After dividing, each individual RUN is taken, and sorted using the insertion sort technique. After that, all sorted RUNs are merged using the merge() function of the merge sort algorithm. In Tim sort, the advantage of using the insertion sort is that insertion sort works efficiently for the array with small size.
Let's see the example of Tim sort algorithm. To understand the working of Tim sort algorithm, let's take an unsorted array. It will be easier to understand the Tim sort via an example.
Suppose the array elements are -
For the simple illustration, let's consider the size of RUN is 4.
Now, divide the given array into two sub-arrays that are -
The first sub-array is
First iteration
a[1] = 10
Second iteration
a[2] = 20
Third iteration
a[3] = 42
The second sub-array is
First iteration
a[1] = 25
Second iteration
a[2] = 1
Third iteration
a[3] = 19
Now, merge both sorted subarrays to get the final array as -
Now, the array is completely sorted.
- Best Case Complexity - It occurs when there is no sorting required, i.e. the array is already sorted. The best-case time complexity of Tim sort is O(n).
- Average Case Complexity - It occurs when the array elements are in jumbled order that is not properly ascending and not properly descending. The average case time complexity of Tim sort is O(n log n).
- Worst Case Complexity - It occurs when the array elements are required to be sorted in reverse order. That means suppose you have to sort the array elements in ascending order, but its elements are in descending order. The worst-case time complexity of Tim sort is O(n log n).
The space complexity of Tim sort is O(n).
import java.util.Arrays;
public class TimSort {
final static int RUN = 32;
final static int[] numbers = {38, 10, 29, 25, 23, 6, 2, 30, 15, 56, 7};
public static void main(String[] args) {
System.out.print("Before sorting - ");
System.out.println(Arrays.toString(numbers));
timSort(numbers);
System.out.print("After sorting - ");
System.out.println(Arrays.toString(numbers));
}
/* Method sorts array with insertion sort from starting index to ending index which is of size atmost RUN */
public static void insertionSort(int[] arr, int begin, int finish) {
for (int i = begin + 1; i <= finish; i++) {
int temp = arr[i];
int j = i - 1;
while (j >= begin && temp <= arr[j]) {
arr[j + 1] = arr[j];
j = j - 1;
}
arr[j + 1] = temp;
}
}
/* Method to merge the sorted runs */
public static void merge(int[] arr, int start, int mid, int finish) {
int[] leftArray = new int[mid - start + 1]; //n1
int[] rightArray = new int[finish - mid]; //n2
System.arraycopy(arr, start, leftArray, 0, mid - start + 1);
System.arraycopy(arr, mid + 1, rightArray, 0, finish - mid);
int i = 0;
int j = 0;
int k = start;
while (i < leftArray.length && j < rightArray.length) {
if (leftArray[i] <= rightArray[j]) {
arr[k++] = leftArray[i++];
} else {
arr[k++] = rightArray[j++];
}
}
while (i < leftArray.length) {
arr[k++] = leftArray[i++];
}
while (j < rightArray.length) {
arr[k++] = rightArray[j++];
}
}
/* method to implement tim sort */
public static void timSort(int[] arr) {
int n = arr.length;
for (int i = 0; i < n; i += RUN) {
insertionSort(arr, i, min((i + RUN - 1), (n - 1)));
}
for (int size = RUN; size < n; size = 2 * size) {
for (int beg = 0; beg < n; beg += 2 * size) {
/* find ending point of left subarray. The starting point of right sub array is mid + 1 */
int mid = beg + size - 1;
int end = min((beg + 2 * size - 1), (n - 1));
/* Merge subarray a[beg...mid] and a[mid +1...end] */
if (mid < end)
merge(arr, beg, mid, end);
}
}
}
public static int min(int a, int b) {
if (a < b) {
return a;
} else {
return b;
}
}
}