diff --git a/csharp-algorithms/MergeSort/MergeSort/Merge.cs b/csharp-algorithms/MergeSort/MergeSort/Merge.cs index 8840af5895..4c93066a9a 100644 --- a/csharp-algorithms/MergeSort/MergeSort/Merge.cs +++ b/csharp-algorithms/MergeSort/MergeSort/Merge.cs @@ -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 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; + } +} diff --git a/csharp-algorithms/MergeSort/MergeSort/MergeBenchmarks.cs b/csharp-algorithms/MergeSort/MergeSort/MergeBenchmarks.cs new file mode 100644 index 0000000000..531cc82f28 --- /dev/null +++ b/csharp-algorithms/MergeSort/MergeSort/MergeBenchmarks.cs @@ -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); + } +} diff --git a/csharp-algorithms/MergeSort/MergeSort/MergeSort.csproj b/csharp-algorithms/MergeSort/MergeSort/MergeSort.csproj index 79e7148fd0..62be4f867f 100644 --- a/csharp-algorithms/MergeSort/MergeSort/MergeSort.csproj +++ b/csharp-algorithms/MergeSort/MergeSort/MergeSort.csproj @@ -2,13 +2,13 @@ Exe - net6.0 + net10.0 enable enable - + diff --git a/csharp-algorithms/MergeSort/MergeSort/Program.cs b/csharp-algorithms/MergeSort/MergeSort/Program.cs index 1376e8ed53..7812d3657d 100644 --- a/csharp-algorithms/MergeSort/MergeSort/Program.cs +++ b/csharp-algorithms/MergeSort/MergeSort/Program.cs @@ -1,4 +1,4 @@ using BenchmarkDotNet.Running; using MergeSort; -var summary = BenchmarkRunner.Run(); \ No newline at end of file +BenchmarkRunner.Run(args: args); diff --git a/csharp-algorithms/MergeSort/MergeSortTest/MergeSortTest.csproj b/csharp-algorithms/MergeSort/MergeSortTest/MergeSortTest.csproj index 9a378fd9a3..ebc67b0f1a 100644 --- a/csharp-algorithms/MergeSort/MergeSortTest/MergeSortTest.csproj +++ b/csharp-algorithms/MergeSort/MergeSortTest/MergeSortTest.csproj @@ -1,17 +1,22 @@ - net6.0 + net10.0 + enable enable false - - - - + + + + + + + + diff --git a/csharp-algorithms/MergeSort/MergeSortTest/MergeUnitTests.cs b/csharp-algorithms/MergeSort/MergeSortTest/MergeUnitTests.cs index 7267ef6e92..bec5483748 100644 --- a/csharp-algorithms/MergeSort/MergeSortTest/MergeUnitTests.cs +++ b/csharp-algorithms/MergeSort/MergeSortTest/MergeUnitTests.cs @@ -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); } -} \ No newline at end of file +}