Skip to content

Commit

Permalink
Add implementation for basic timsorter
Browse files Browse the repository at this point in the history
  • Loading branch information
Kalkwst committed Sep 23, 2024
1 parent 9eb2196 commit 1dad0c8
Show file tree
Hide file tree
Showing 2 changed files with 156 additions and 0 deletions.
60 changes: 60 additions & 0 deletions Algorithms.Tests/Sorters/Comparison/BasicTeamSorterTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
using Algorithms.Sorters.Comparison;
using NUnit.Framework;
using System.Collections.Generic;

namespace Algorithms.Tests.Sorters.Comparison
{
[TestFixture]
public class BasicTimSorterTests
{
private BasicTimSorter<int> sorter = new BasicTimSorter<int>(Comparer<int>.Default);

Check warning on line 10 in Algorithms.Tests/Sorters/Comparison/BasicTeamSorterTests.cs

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

Algorithms.Tests/Sorters/Comparison/BasicTeamSorterTests.cs#L10

Make 'sorter' 'readonly'.

[Test]
public void Sort_EmptyArray_DoesNotThrow()
{
var array = new int[] { };
Assert.DoesNotThrow(() => sorter.Sort(array));
Assert.That(array, Is.Empty);
}

[Test]
public void Sort_SingleElementArray_DoesNotChangeArray()
{
var array = new[] { 1 };
sorter.Sort(array);
Assert.That(array, Is.EqualTo(new[] { 1 }));
}

[Test]
public void Sort_AlreadySortedArray_DoesNotChangeArray()
{
var array = new[] { 1, 2, 3, 4, 5 };
sorter.Sort(array);
Assert.That(array, Is.EqualTo(new[] { 1, 2, 3, 4, 5 }));
}

[Test]
public void Sort_UnsortedArray_SortsCorrectly()
{
var array = new[] { 5, 3, 1, 4, 2 };
sorter.Sort(array);
Assert.That(array, Is.EqualTo(new[] { 1, 2, 3, 4, 5 }));
}

[Test]
public void Sort_ReverseSortedArray_SortsCorrectly()
{
var array = new[] { 5, 4, 3, 2, 1 };
sorter.Sort(array);
Assert.That(array, Is.EqualTo(new[] { 1, 2, 3, 4, 5 }));
}

[Test]
public void Sort_ArrayWithDuplicates_SortsCorrectly()
{
var array = new[] { 3, 1, 2, 3, 1, 2 };
sorter.Sort(array);
Assert.That(array, Is.EqualTo(new[] { 1, 1, 2, 2, 3, 3 }));
}
}
}
96 changes: 96 additions & 0 deletions Algorithms/Sorters/Comparison/BasicTimSorter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
using System;
using System.Collections;
using System.Collections.Generic;

namespace Algorithms.Sorters.Comparison
{
public class BasicTimSorter<T>
{
private readonly int minRuns = 32;
private readonly IComparer<T> comparer;

public BasicTimSorter(IComparer<T> comparer)
{
this.comparer = comparer ?? Comparer<T>.Default;
}

public void Sort(T[] array)
{
var n = array.Length;

// Step 1: Sort small pieces of the array using Insertion Sort
for (var i = 0; i < n; i += minRuns)
{
InsertionSort(array, i, Math.Min(i + minRuns - 1, n - 1));
}

// Step 2: Merge sorted runs using Merge Sort
for (var size = minRuns; size < n; size *= 2)
{
for (var left = 0; left < n; left += 2 * size)
{
var mid = left + size - 1;
var right = Math.Min(left + 2 * size - 1, n - 1);

if (mid < right)
{
Merge(array, left, mid, right);
}
}
}
}

private void InsertionSort(T[] array, int left, int right)
{
for (var i = left + 1; i <= right; i++)
{
var key = array[i];
var j = i - 1;

while (j >= left && comparer.Compare(array[j], key) > 0)
{
array[j + 1] = array[j];
j--;
}

array[j + 1] = key;
}
}

private void Merge(T[] array, int left, int mid, int right)
{
var leftSegment = new ArraySegment<T>(array, left, mid - left + 1);
var rightSegment = new ArraySegment<T>(array, mid + 1, right - mid);

var leftArray = leftSegment.ToArray();
var rightArray = rightSegment.ToArray();

int i = 0, j = 0, k = left;

Check notice on line 68 in Algorithms/Sorters/Comparison/BasicTimSorter.cs

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

Algorithms/Sorters/Comparison/BasicTimSorter.cs#L68

Declare 'j' in a separate statement.

// Merge the two subarrays back into the main array
while (i < leftArray.Length && j < rightArray.Length)
{
if (comparer.Compare(leftArray[i], rightArray[j]) <= 0)

Check notice on line 73 in Algorithms/Sorters/Comparison/BasicTimSorter.cs

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

Algorithms/Sorters/Comparison/BasicTimSorter.cs#L73

Use the '?:' operator here.
{
array[k++] = leftArray[i++];
}
else
{
array[k++] = rightArray[j++];
}
}

// Copy remaining elements from leftArray, if any
while (i < leftArray.Length)
{
array[k++] = leftArray[i++];
}

// Copy remaining elements from rightArray, if any
while (j < rightArray.Length)
{
array[k++] = rightArray[j++];
}
}
}
}

0 comments on commit 1dad0c8

Please sign in to comment.