Skip to content

Commit 115a0fa

Browse files
committed
Add implementation for basic timsorter
1 parent 9eb2196 commit 115a0fa

File tree

3 files changed

+157
-0
lines changed

3 files changed

+157
-0
lines changed
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
using Algorithms.Sorters.Comparison;
2+
using NUnit.Framework;
3+
using System.Collections.Generic;
4+
5+
namespace Algorithms.Tests.Sorters.Comparison
6+
{
7+
[TestFixture]
8+
public class BasicTimSorterTests
9+
{
10+
private BasicTimSorter<int> sorter = new BasicTimSorter<int>(Comparer<int>.Default);
11+
12+
[Test]
13+
public void Sort_EmptyArray_DoesNotThrow()
14+
{
15+
var array = new int[] { };
16+
Assert.DoesNotThrow(() => sorter.Sort(array));
17+
Assert.That(array, Is.Empty);
18+
}
19+
20+
[Test]
21+
public void Sort_SingleElementArray_DoesNotChangeArray()
22+
{
23+
var array = new[] { 1 };
24+
sorter.Sort(array);
25+
Assert.That(array, Is.EqualTo(new[] { 1 }));
26+
}
27+
28+
[Test]
29+
public void Sort_AlreadySortedArray_DoesNotChangeArray()
30+
{
31+
var array = new[] { 1, 2, 3, 4, 5 };
32+
sorter.Sort(array);
33+
Assert.That(array, Is.EqualTo(new[] { 1, 2, 3, 4, 5 }));
34+
}
35+
36+
[Test]
37+
public void Sort_UnsortedArray_SortsCorrectly()
38+
{
39+
var array = new[] { 5, 3, 1, 4, 2 };
40+
sorter.Sort(array);
41+
Assert.That(array, Is.EqualTo(new[] { 1, 2, 3, 4, 5 }));
42+
}
43+
44+
[Test]
45+
public void Sort_ReverseSortedArray_SortsCorrectly()
46+
{
47+
var array = new[] { 5, 4, 3, 2, 1 };
48+
sorter.Sort(array);
49+
Assert.That(array, Is.EqualTo(new[] { 1, 2, 3, 4, 5 }));
50+
}
51+
52+
[Test]
53+
public void Sort_ArrayWithDuplicates_SortsCorrectly()
54+
{
55+
var array = new[] { 3, 1, 2, 3, 1, 2 };
56+
sorter.Sort(array);
57+
Assert.That(array, Is.EqualTo(new[] { 1, 1, 2, 2, 3, 3 }));
58+
}
59+
}
60+
}
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
using System;
2+
using System.Collections;
3+
using System.Collections.Generic;
4+
5+
namespace Algorithms.Sorters.Comparison
6+
{
7+
public class BasicTimSorter<T>
8+
{
9+
private readonly int minRuns = 32;
10+
private readonly IComparer<T> comparer;
11+
12+
public BasicTimSorter(IComparer<T> comparer)
13+
{
14+
this.comparer = comparer ?? Comparer<T>.Default;
15+
}
16+
17+
public void Sort(T[] array)
18+
{
19+
var n = array.Length;
20+
21+
// Step 1: Sort small pieces of the array using Insertion Sort
22+
for (var i = 0; i < n; i += minRuns)
23+
{
24+
InsertionSort(array, i, Math.Min(i + minRuns - 1, n - 1));
25+
}
26+
27+
// Step 2: Merge sorted runs using Merge Sort
28+
for (var size = minRuns; size < n; size *= 2)
29+
{
30+
for (var left = 0; left < n; left += 2 * size)
31+
{
32+
var mid = left + size - 1;
33+
var right = Math.Min(left + 2 * size - 1, n - 1);
34+
35+
if (mid < right)
36+
{
37+
Merge(array, left, mid, right);
38+
}
39+
}
40+
}
41+
}
42+
43+
private void InsertionSort(T[] array, int left, int right)
44+
{
45+
for (var i = left + 1; i <= right; i++)
46+
{
47+
var key = array[i];
48+
var j = i - 1;
49+
50+
while (j >= left && comparer.Compare(array[j], key) > 0)
51+
{
52+
array[j + 1] = array[j];
53+
j--;
54+
}
55+
56+
array[j + 1] = key;
57+
}
58+
}
59+
60+
private void Merge(T[] array, int left, int mid, int right)
61+
{
62+
var leftSegment = new ArraySegment<T>(array, left, mid - left + 1);
63+
var rightSegment = new ArraySegment<T>(array, mid + 1, right - mid);
64+
65+
var leftArray = leftSegment.ToArray();
66+
var rightArray = rightSegment.ToArray();
67+
68+
int i = 0, j = 0, k = left;
69+
70+
// Merge the two subarrays back into the main array
71+
while (i < leftArray.Length && j < rightArray.Length)
72+
{
73+
if (comparer.Compare(leftArray[i], rightArray[j]) <= 0)
74+
{
75+
array[k++] = leftArray[i++];
76+
}
77+
else
78+
{
79+
array[k++] = rightArray[j++];
80+
}
81+
}
82+
83+
// Copy remaining elements from leftArray, if any
84+
while (i < leftArray.Length)
85+
{
86+
array[k++] = leftArray[i++];
87+
}
88+
89+
// Copy remaining elements from rightArray, if any
90+
while (j < rightArray.Length)
91+
{
92+
array[k++] = rightArray[j++];
93+
}
94+
}
95+
}
96+
}

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ find more than one implementation for the same objective but using different alg
124124
* [Selection Sort](./Algorithms/Sorters/Comparison/SelectionSorter.cs)
125125
* [Shell Sort](./Algorithms/Sorters/Comparison/ShellSorter.cs)
126126
* [Tim Sort](./Algorithms/Sorters/Comparison/TimSorter.cs)
127+
* [Simplified Tim Sort](./Algorithms/Sorters/Comparison/BasicTimSorter.cs)
127128
* [External](./Algorithms/Sorters/External)
128129
* [Merge Sort](./Algorithms/Sorters/External/ExternalMergeSorter.cs)
129130
* [Integer](./Algorithms/Sorters/Integer)

0 commit comments

Comments
 (0)