Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
170 changes: 77 additions & 93 deletions csharp-algorithms/MergeSort/MergeSort/Merge.cs
Original file line number Diff line number Diff line change
@@ -1,97 +1,81 @@
using BenchmarkDotNet.Attributes;
namespace MergeSort;

namespace MergeSort
public class Merge
{
public class Merge
public int[] SortArray(int[] array, int left, int right)
{
public IEnumerable<object[]> ArrayData()
{
yield return new object[] { GenerateRandomNumber(200), 0, 199, "Small Unsorted" };
yield return new object[] { GenerateRandomNumber(2000), 0, 1999, "Medium Unsorted" };
yield return new object[] { GenerateRandomNumber(20000), 0, 19999, "Large Unsorted" };
yield return new object[] { GenerateSortedNumber(200), 0, 199,"Small Sorted" };
yield return new object[] { GenerateSortedNumber(2000), 0, 1999, "Medium Sorted" };
yield return new object[] { GenerateSortedNumber(20000), 0, 19999, "Large Sorted" };
}

public void MergeArray(int[] array, int left, int middle, int right)
{
var leftArrayLength = middle - left + 1;
var rightArrayLength = right - middle;
var leftTempArray = new int[leftArrayLength];
var rightTempArray = new int[rightArrayLength];
int i, j;

for (i = 0; i < leftArrayLength; ++i)
leftTempArray[i] = array[left + i];
for (j = 0; j < rightArrayLength; ++j)
rightTempArray[j] = array[middle + 1 + j];

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

while (i < leftArrayLength && j < rightArrayLength)
{
if (leftTempArray[i] <= rightTempArray[j])
{
array[k++] = leftTempArray[i++];
}
else
{
array[k++] = rightTempArray[j++];
}
}

while (i < leftArrayLength)
{
array[k++] = leftTempArray[i++];
}

while (j < rightArrayLength)
{
array[k++] = rightTempArray[j++];
}
}

[ArgumentsSource(nameof(ArrayData))]
[Benchmark]
public int[] SortArray(int[] array, int left, int right, string arrayName)
{
if (left < right)
{
int middle = left + (right - left) / 2;

SortArray(array, left, middle, arrayName);
SortArray(array, middle + 1, right, arrayName);

MergeArray(array, left, middle, right);
}

return array;
}

public static int[] GenerateRandomNumber(int size)
{
var array = new int[size];
var rand = new Random();
var maxNum = 10000;

for (int i = 0; i < size; i++)
array[i] = rand.Next(maxNum + 1);

return array;
}

public static int[] GenerateSortedNumber(int size)
{
var array = new int[size];

for (int i = 0; i < size; i++)
array[i] = i;

return array;
}
}
}
if (left < right)
{
int middle = left + (right - left) / 2;

SortArray(array, left, middle);
SortArray(array, middle + 1, right);

MergeArray(array, left, middle, right);
}

return array;
}

public void MergeArray(int[] array, int left, int middle, int right)
{
var leftArrayLength = middle - left + 1;
var rightArrayLength = right - middle;
var leftTempArray = new int[leftArrayLength];
var rightTempArray = new int[rightArrayLength];
int i, j;

for (i = 0; i < leftArrayLength; ++i)
leftTempArray[i] = array[left + i];
for (j = 0; j < rightArrayLength; ++j)
rightTempArray[j] = array[middle + 1 + j];

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

while (i < leftArrayLength && j < rightArrayLength)
{
if (leftTempArray[i] <= rightTempArray[j])
{
array[k++] = leftTempArray[i++];
}
else
{
array[k++] = rightTempArray[j++];
}
}

while (i < leftArrayLength)
{
array[k++] = leftTempArray[i++];
}

while (j < rightArrayLength)
{
array[k++] = rightTempArray[j++];
}
}

public static int[] GenerateRandomNumber(int size)
{
var array = new int[size];
var rand = new Random();
var maxNum = 10000;

for (int i = 0; i < size; i++)
array[i] = rand.Next(maxNum + 1);

return array;
}

public static int[] GenerateSortedNumber(int size)
{
var array = new int[size];

for (int i = 0; i < size; i++)
array[i] = i;

return array;
}
}
34 changes: 34 additions & 0 deletions csharp-algorithms/MergeSort/MergeSort/MergeBenchmarks.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
using BenchmarkDotNet.Attributes;

namespace MergeSort;

[MemoryDiagnoser]
public class MergeBenchmarks
{
private readonly Merge _merge = new();
private int[] _source = [];
private int[] _work = [];

[Params(200, 2_000, 20_000)]
public int Size { get; set; }

[Params("Random", "Sorted")]
public string Input { get; set; } = "Random";

[GlobalSetup]
public void Setup()
{
_source = Input == "Random"
? Merge.GenerateRandomNumber(Size)
: Merge.GenerateSortedNumber(Size);
_work = new int[Size];
}

[Benchmark]
public int[] SortArray()
{
_source.CopyTo(_work, 0);

return _merge.SortArray(_work, 0, _work.Length - 1);
}
}
4 changes: 2 additions & 2 deletions csharp-algorithms/MergeSort/MergeSort/MergeSort.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="BenchmarkDotNet" Version="0.13.1" />
<PackageReference Include="BenchmarkDotNet" Version="0.15.8" />
</ItemGroup>

</Project>
2 changes: 1 addition & 1 deletion csharp-algorithms/MergeSort/MergeSort/Program.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using BenchmarkDotNet.Running;
using MergeSort;

var summary = BenchmarkRunner.Run<Merge>();
BenchmarkRunner.Run<MergeBenchmarks>(args: args);
15 changes: 10 additions & 5 deletions csharp-algorithms/MergeSort/MergeSortTest/MergeSortTest.csproj
Original file line number Diff line number Diff line change
@@ -1,17 +1,22 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>

<IsPackable>false</IsPackable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.11.0" />
<PackageReference Include="MSTest.TestAdapter" Version="2.2.7" />
<PackageReference Include="MSTest.TestFramework" Version="2.2.7" />
<PackageReference Include="coverlet.collector" Version="3.1.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.11.0" />
<PackageReference Include="MSTest.TestAdapter" Version="4.5.2" />
<PackageReference Include="MSTest.TestFramework" Version="4.5.2" />
<PackageReference Include="coverlet.collector" Version="10.1.0" />
</ItemGroup>

<ItemGroup>
<Using Include="Microsoft.VisualStudio.TestTools.UnitTesting" />
</ItemGroup>

<ItemGroup>
Expand Down
90 changes: 59 additions & 31 deletions csharp-algorithms/MergeSort/MergeSortTest/MergeUnitTests.cs
Original file line number Diff line number Diff line change
@@ -1,44 +1,72 @@
using MergeSort;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace MergeSortTest
namespace MergeSortTest;

[TestClass]
public class MergeUnitTests
{
[TestClass]
public class MergeUnitTests
[TestMethod]
public void GivenUnsortedArray_ThenReturnSortedArray()
{
[TestMethod]
public void GivenUnsortedArray_ThenReturnSortedArray()
{
var array = new int[] { 73, 57, 49, 99, 133, 20, 1 };
var expected = new int[] { 1, 20, 49, 57, 73, 99, 133 };
var sortFunction = new Merge();
var array = new int[] { 73, 57, 49, 99, 133, 20, 1 };
var expected = new int[] { 1, 20, 49, 57, 73, 99, 133 };
var sortFunction = new Merge();

var sortedArray = sortFunction.SortArray(array, 0, array.Length - 1);

Assert.IsNotNull(sortedArray);
CollectionAssert.AreEqual(expected, sortedArray);
}

var sortedArray = sortFunction.SortArray(array, 0, array.Length - 1, string.Empty);
[TestMethod]
public void GivenUnsortedArray_CheckInstanceType()
{
var sortFunction = new Merge();
var array = Merge.GenerateRandomNumber(200);

Assert.IsNotNull(sortedArray);
CollectionAssert.AreEqual(sortedArray, expected);
}
var sortedArray = sortFunction.SortArray(array, 0, array.Length - 1);

[TestMethod]
public void GivenUnsortedArray_CheckInstanceType()
{
var sortFunction = new Merge();
var array = Merge.GenerateRandomNumber(200);
Assert.IsInstanceOfType(sortedArray, typeof(int[]));
}

var sortedArray = sortFunction.SortArray(array, 0, array.Length-1, string.Empty);
[TestMethod]
public void GivenUnsortedArray_CheckSortedNotNull()
{
var sortFunction = new Merge();
var array = Merge.GenerateRandomNumber(200);

Assert.IsInstanceOfType(sortedArray, typeof(int[]));
}
var sortedArray = sortFunction.SortArray(array, 0, array.Length - 1);

[TestMethod]
public void GivenUnsortedArray_CheckSortedNotNull()
{
var sortFunction = new Merge();
var array = Merge.GenerateRandomNumber(200);
Assert.IsNotNull(sortedArray);
}

[TestMethod]
public void GivenRandomArray_WhenSorted_ThenMatchesArraySort()
{
var sortFunction = new Merge();
var array = Merge.GenerateRandomNumber(1_000);
var expected = (int[])array.Clone();
Array.Sort(expected);

var sortedArray = sortFunction.SortArray(array, 0, array.Length - 1);

CollectionAssert.AreEqual(expected, sortedArray);
}

[TestMethod]
[DataRow(new int[] { })]
[DataRow(new int[] { 42 })]
[DataRow(new int[] { 5, 3, 5, 1, 3, 5 })]
[DataRow(new int[] { 1, 2, 3, 4, 5, 6 })]
[DataRow(new int[] { 6, 5, 4, 3, 2, 1 })]
public void GivenEdgeCaseArray_WhenSorted_ThenMatchesArraySort(int[] array)
{
var sortFunction = new Merge();
var expected = (int[])array.Clone();
Array.Sort(expected);

var sortedArray = sortFunction.SortArray(array, 0, array.Length-1, string.Empty);
var sortedArray = sortFunction.SortArray(array, 0, array.Length - 1);

Assert.IsNotNull(sortedArray);
}
CollectionAssert.AreEqual(expected, sortedArray);
}
}
}
Loading