├── .gitignore ├── .travis.yml ├── README.md ├── project.json ├── src ├── BubbleSort.cs ├── BubbleSortOptimised.cs ├── BucketSort.cs ├── CocktailSort.cs ├── CombSort.cs ├── CountingSort.cs ├── GnomeSort.cs ├── Heapsort.cs ├── IGenericSortingAlgorithm.cs ├── IIntegerSortingAlgorithm.cs ├── InsertionSort.cs ├── MergeSort.cs ├── MergeSortBottomUp.cs ├── OddEvenSort.cs ├── Quicksort.cs ├── RadixSort.cs └── SelectionSort.cs └── test ├── BaseGenericSortingAlgorithmTest.cs ├── BaseIntegerSortingAlgorithmTest.cs ├── BubbleSortOptimisedTest.cs ├── BubbleSortTest.cs ├── BucketSortTest.cs ├── CocktailSortTest.cs ├── CombSortTest.cs ├── CountingSortTest.cs ├── GnomeSortTest.cs ├── HeapsortTest.cs ├── InsertionSortTest.cs ├── MergeSortBottomUpTest.cs ├── MergeSortTest.cs ├── OddEvenSortTest.cs ├── Quicksort.cs ├── RadixSortTest.cs └── SelectionSortTest.cs /.gitignore: -------------------------------------------------------------------------------- 1 | bin/ 2 | obj/ 3 | project.lock.json -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: c++ 2 | sudo: required 3 | dist: trusty 4 | before_install: 5 | - sudo sh -c 'echo "deb [arch=amd64] https://apt-mo.trafficmanager.net/repos/dotnet-release/ trusty main" > /etc/apt/sources.list.d/dotnetdev.list' 6 | - sudo apt-key adv --keyserver apt-mo.trafficmanager.net --recv-keys 417A0893 7 | - sudo apt-get update 8 | - sudo apt-get install -y dotnet-dev-1.0.0-preview2-003121 9 | install: 10 | - dotnet restore 11 | script: 12 | - dotnet test -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## csharp-sorting 2 | 3 | [![Build Status](https://travis-ci.org/gwtw/csharp-sorting.svg?branch=master)](https://travis-ci.org/gwtw/csharp-sorting) 4 | 5 | A collection of sorting algorithms written in C# for [Growing with the Web](http://www.growingwiththeweb.com/). 6 | 7 | ## Dependencies 8 | 9 | This project requires [.NET Core](https://www.microsoft.com/net/core). 10 | 11 | ## Build 12 | 13 | ```bash 14 | dotnet restore 15 | ``` 16 | 17 | ## Test 18 | 19 | ```bash 20 | dotnet test 21 | ``` 22 | 23 | ## See also 24 | 25 | - [Complexity table for sorting algorithms](https://github.com/gwtw/js-sorting/blob/master/lib/README.md) -------------------------------------------------------------------------------- /project.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "1.0.0-*", 3 | "testRunner": "xunit", 4 | "buildOptions": { 5 | "debugType": "portable", 6 | "emitEntryPoint": false, 7 | "outputName": "GrowingWithTheWeb.Sorting" 8 | }, 9 | "dependencies": { 10 | "xunit": "2.2.0-beta2-build3300", 11 | "dotnet-test-xunit": "2.2.0-preview2-build1029" 12 | }, 13 | "frameworks": { 14 | "netcoreapp1.0": { 15 | "dependencies": { 16 | "Microsoft.NETCore.App": { 17 | "type": "platform", 18 | "version": "1.0.0" 19 | } 20 | }, 21 | "imports": "dnxcore50" 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/BubbleSort.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace GrowingWithTheWeb.Sorting 5 | { 6 | public class BubbleSort : IGenericSortingAlgorithm where T : IComparable 7 | { 8 | public void Sort(IList list) 9 | { 10 | for (int i = 0; i < list.Count - 1; i++) 11 | { 12 | for (int j = 1; j < list.Count - i; j++) 13 | { 14 | if (list[j - 1].CompareTo(list[j]) > 0) 15 | { 16 | Swap(list, j, j - 1); 17 | } 18 | } 19 | } 20 | } 21 | 22 | private void Swap(IList list, int a, int b) 23 | { 24 | T temp = list[a]; 25 | list[a] = list[b]; 26 | list[b] = temp; 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /src/BubbleSortOptimised.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace GrowingWithTheWeb.Sorting 5 | { 6 | public class BubbleSortOptimised : IGenericSortingAlgorithm where T : IComparable 7 | { 8 | public void Sort(IList list) 9 | { 10 | int unsortedBelow = list.Count; 11 | while (unsortedBelow != 0) { 12 | int lastSwap = 0; 13 | for (int i = 1; i < unsortedBelow; i++) { 14 | if (list[i - 1].CompareTo(list[i]) > 0) { 15 | Swap(list, i, i - 1); 16 | lastSwap = i; 17 | } 18 | } 19 | unsortedBelow = lastSwap; 20 | } 21 | } 22 | 23 | private void Swap(IList list, int a, int b) 24 | { 25 | T temp = list[a]; 26 | list[a] = list[b]; 27 | list[b] = temp; 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /src/BucketSort.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace GrowingWithTheWeb.Sorting 4 | { 5 | public class BucketSort : IIntegerSortingAlgorithm { 6 | private const int DefaultBucketSize = 5; 7 | 8 | public void Sort(int[] array) { 9 | Sort(array, DefaultBucketSize); 10 | } 11 | 12 | public void Sort(int[] array, int bucketSize) { 13 | if (array.Length == 0) { 14 | return; 15 | } 16 | 17 | // Determine minimum and maximum values 18 | int minValue = array[0]; 19 | int maxValue = array[0]; 20 | for (int i = 1; i < array.Length; i++) { 21 | if (array[i] < minValue) { 22 | minValue = array[i]; 23 | } else if (array[i] > maxValue) { 24 | maxValue = array[i]; 25 | } 26 | } 27 | 28 | // Initialise buckets 29 | int bucketCount = (maxValue - minValue) / bucketSize + 1; 30 | IList> buckets = new List>(bucketCount); 31 | for (int i = 0; i < bucketCount; i++) { 32 | buckets.Add(new List()); 33 | } 34 | 35 | // Distribute input array values into buckets 36 | for (int i = 0; i < array.Length; i++) { 37 | buckets[(array[i] - minValue) / bucketSize].Add(array[i]); 38 | } 39 | 40 | // Sort buckets and place back into input array 41 | int currentIndex = 0; 42 | var insertionSort = new InsertionSort(); 43 | for (int i = 0; i < buckets.Count; i++) { 44 | int[] bucketArray = buckets[i].ToArray(); 45 | insertionSort.Sort(bucketArray); 46 | for (int j = 0; j < bucketArray.Length; j++) { 47 | array[currentIndex++] = bucketArray[j]; 48 | } 49 | } 50 | } 51 | } 52 | } -------------------------------------------------------------------------------- /src/CocktailSort.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace GrowingWithTheWeb.Sorting 5 | { 6 | public class CocktailSort : IGenericSortingAlgorithm where T : IComparable 7 | { 8 | public void Sort(IList list) 9 | { 10 | int start = -1; 11 | int end = list.Count - 2; 12 | bool swapped; 13 | 14 | do { 15 | swapped = false; 16 | for (int i = ++start; i <= end; i++) { 17 | if (list[i].CompareTo(list[i + 1]) > 0) { 18 | Swap(list, i, i + 1); 19 | swapped = true; 20 | } 21 | } 22 | 23 | if (!swapped) { 24 | break; 25 | } 26 | 27 | swapped = false; 28 | for (int i = --end; i >= start; i--) { 29 | if (list[i].CompareTo(list[i + 1]) > 0) { 30 | Swap(list, i, i + 1); 31 | swapped = true; 32 | } 33 | } 34 | } while (swapped); 35 | } 36 | 37 | private void Swap(IList list, int a, int b) 38 | { 39 | T temp = list[a]; 40 | list[a] = list[b]; 41 | list[b] = temp; 42 | } 43 | } 44 | } -------------------------------------------------------------------------------- /src/CombSort.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace GrowingWithTheWeb.Sorting 5 | { 6 | public class CombSort : IGenericSortingAlgorithm where T : IComparable 7 | { 8 | public void Sort(IList list) 9 | { 10 | int gap = list.Count; 11 | float shrinkFactor = 1.3f; 12 | bool swapped = false; 13 | 14 | while (gap > 1 || swapped) { 15 | if (gap > 1) { 16 | gap = (int)(gap / shrinkFactor); 17 | } 18 | 19 | swapped = false; 20 | 21 | for (int i = 0; gap + i < list.Count; i++) { 22 | if (list[i].CompareTo(list[i + gap]) > 0) { 23 | Swap(list, i, i + gap); 24 | swapped = true; 25 | } 26 | } 27 | } 28 | } 29 | 30 | private void Swap(IList list, int a, int b) 31 | { 32 | T temp = list[a]; 33 | list[a] = list[b]; 34 | list[b] = temp; 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /src/CountingSort.cs: -------------------------------------------------------------------------------- 1 | namespace GrowingWithTheWeb.Sorting 2 | { 3 | public class CountingSort : IIntegerSortingAlgorithm { 4 | public void Sort(int[] array) { 5 | if (array.Length == 0) { 6 | return; 7 | } 8 | 9 | // Determine minimum and maximum values 10 | int minValue = array[0]; 11 | int maxValue = array[0]; 12 | for (int i = 1; i < array.Length; i++) { 13 | if (array[i] < minValue) { 14 | minValue = array[i]; 15 | } else if (array[i] > maxValue) { 16 | maxValue = array[i]; 17 | } 18 | } 19 | 20 | Sort(array, minValue, maxValue); 21 | } 22 | 23 | public void Sort(int[] array, int minValue, int maxValue) { 24 | int[] buckets = new int[maxValue - minValue + 1]; 25 | 26 | for (int i = 0; i < array.Length; i++) { 27 | buckets[array[i] - minValue]++; 28 | } 29 | 30 | int sortedIndex = 0; 31 | for (int i = 0; i < buckets.Length; i++) { 32 | while (buckets[i] > 0) { 33 | array[sortedIndex++] = i + minValue; 34 | buckets[i]--; 35 | } 36 | } 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /src/GnomeSort.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace GrowingWithTheWeb.Sorting 5 | { 6 | public class GnomeSort : IGenericSortingAlgorithm where T : IComparable 7 | { 8 | public void Sort(IList list) 9 | { 10 | int i = 0; 11 | while (i < list.Count) { 12 | if (i == 0 || list[i - 1].CompareTo(list[i]) <= 0) { 13 | i++; 14 | } else { 15 | Swap(list, i, i - 1); 16 | i--; 17 | } 18 | } 19 | } 20 | 21 | private void Swap(IList list, int a, int b) 22 | { 23 | T temp = list[a]; 24 | list[a] = list[b]; 25 | list[b] = temp; 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /src/Heapsort.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace GrowingWithTheWeb.Sorting 5 | { 6 | public class Heapsort : IGenericSortingAlgorithm where T : IComparable 7 | { 8 | public void Sort(IList list) 9 | { 10 | int heapSize = list.Count; 11 | BuildHeap(list, heapSize); 12 | while (heapSize > 1) { 13 | Swap(list, 0, heapSize - 1); 14 | heapSize--; 15 | Heapify(list, heapSize, 0); 16 | } 17 | } 18 | 19 | private void BuildHeap(IList list, int heapSize) { 20 | for (int i = (int)(list.Count / 2); i >= 0; i--) { 21 | Heapify(list, heapSize, i); 22 | } 23 | } 24 | 25 | private void Heapify(IList list, int heapSize, int i) { 26 | int left = i * 2 + 1; 27 | int right = i * 2 + 2; 28 | int largest; 29 | if (left < heapSize && list[left].CompareTo(list[i]) > 0) 30 | largest = left; 31 | else 32 | largest = i; 33 | if (right < heapSize && list[right].CompareTo(list[largest]) > 0) 34 | largest = right; 35 | if (largest != i) { 36 | Swap(list, i, largest); 37 | Heapify(list, heapSize, largest); 38 | } 39 | } 40 | 41 | private void Swap(IList list, int a, int b) 42 | { 43 | T temp = list[a]; 44 | list[a] = list[b]; 45 | list[b] = temp; 46 | } 47 | } 48 | } -------------------------------------------------------------------------------- /src/IGenericSortingAlgorithm.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | public interface IGenericSortingAlgorithm where T : IComparable { 5 | void Sort(IList list); 6 | } 7 | -------------------------------------------------------------------------------- /src/IIntegerSortingAlgorithm.cs: -------------------------------------------------------------------------------- 1 | public interface IIntegerSortingAlgorithm { 2 | void Sort(int[] array); 3 | } -------------------------------------------------------------------------------- /src/InsertionSort.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace GrowingWithTheWeb.Sorting 5 | { 6 | public class InsertionSort : IGenericSortingAlgorithm where T : IComparable 7 | { 8 | public void Sort(IList list) 9 | { 10 | for (int i = 1; i < list.Count; i++) { 11 | T item = list[i]; 12 | int indexHole = i; 13 | while (indexHole > 0 && list[indexHole - 1].CompareTo(item) > 0) { 14 | list[indexHole] = list[--indexHole]; 15 | } 16 | list[indexHole] = item; 17 | } 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /src/MergeSort.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace GrowingWithTheWeb.Sorting 5 | { 6 | public class MergeSort : IGenericSortingAlgorithm where T : IComparable 7 | { 8 | public void Sort(IList list) { 9 | var sorted = InternalSort(list); 10 | for (var i = 0; i < list.Count; i++) { 11 | list[i] = sorted[i]; 12 | } 13 | } 14 | 15 | public IList InternalSort(IList list) 16 | { 17 | if (list.Count <= 1) 18 | return list; 19 | 20 | int middle = list.Count / 2; 21 | IList left = new T[middle]; 22 | IList right = new T[list.Count - middle]; 23 | 24 | for (int i = 0; i < left.Count; i++) { 25 | left[i] = list[i]; 26 | } 27 | for (int i = 0; i < right.Count; i++) { 28 | right[i] = list[i + left.Count]; 29 | } 30 | 31 | left = InternalSort(left); 32 | right = InternalSort(right); 33 | 34 | return Merge(left, right); 35 | } 36 | 37 | private T[] Merge(IList left, IList right) { 38 | T[] result = new T[left.Count + right.Count]; 39 | int leftIndex = 0; 40 | int rightIndex = 0; 41 | int resultIndex = 0; 42 | while (leftIndex < left.Count || rightIndex < right.Count) { 43 | if (leftIndex < left.Count && rightIndex < right.Count) { 44 | if (left[leftIndex].CompareTo(right[rightIndex]) <= 0) { 45 | result[resultIndex++] = left[leftIndex++]; 46 | } else { 47 | result[resultIndex++] = right[rightIndex++]; 48 | } 49 | } else if (leftIndex < left.Count) { 50 | result[resultIndex++] = left[leftIndex++]; 51 | } else if (rightIndex < right.Count) { 52 | result[resultIndex++] = right[rightIndex++]; 53 | } 54 | } 55 | return result; 56 | } 57 | } 58 | } -------------------------------------------------------------------------------- /src/MergeSortBottomUp.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace GrowingWithTheWeb.Sorting 5 | { 6 | public class MergeSortBottomUp : IGenericSortingAlgorithm where T : IComparable 7 | { 8 | public void Sort(IList list) { 9 | IList workList = new T[list.Count]; 10 | int chunkSize = 1; 11 | while (chunkSize < list.Count) { 12 | int i = 0; 13 | while (i < list.Count - chunkSize) { 14 | Merge(list, i, chunkSize, workList); 15 | i += chunkSize * 2; 16 | } 17 | chunkSize *= 2; 18 | } 19 | } 20 | 21 | private void Merge(IList list, int leftPosition, int chunkSize, IList workList) { 22 | int rightPosition = leftPosition + chunkSize; 23 | int endPosition = Math.Min(leftPosition + chunkSize * 2 - 1, list.Count - 1); 24 | int leftIndex = leftPosition; 25 | int rightIndex = rightPosition; 26 | 27 | for (int i = 0; i <= endPosition - leftPosition; i++) { 28 | if (leftIndex < rightPosition && 29 | (rightIndex > endPosition || 30 | list[leftIndex].CompareTo(list[rightIndex]) <= 0)) { 31 | workList[i] = list[leftIndex++]; 32 | } else { 33 | workList[i] = list[rightIndex++]; 34 | } 35 | } 36 | 37 | for (int i = leftPosition; i <= endPosition; i++) { 38 | list[i] = workList[i - leftPosition]; 39 | } 40 | } 41 | } 42 | } -------------------------------------------------------------------------------- /src/OddEvenSort.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace GrowingWithTheWeb.Sorting 5 | { 6 | public class OddEvenSort : IGenericSortingAlgorithm where T : IComparable 7 | { 8 | public void Sort(IList list) 9 | { 10 | var sorted = false; 11 | while (!sorted) { 12 | sorted = InnerSort(list, 1); 13 | sorted = InnerSort(list, 0) && sorted; 14 | } 15 | } 16 | 17 | private bool InnerSort(IList list, int i) 18 | { 19 | var sorted = true; 20 | for (; i < list.Count - 1; i += 2) 21 | { 22 | if (list[i].CompareTo(list[i + 1]) > 0) 23 | { 24 | Swap(list, i, i + 1); 25 | sorted = false; 26 | } 27 | } 28 | return sorted; 29 | } 30 | 31 | private void Swap(IList list, int a, int b) 32 | { 33 | T temp = list[a]; 34 | list[a] = list[b]; 35 | list[b] = temp; 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /src/Quicksort.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace GrowingWithTheWeb.Sorting 5 | { 6 | public class Quicksort : IGenericSortingAlgorithm where T : IComparable 7 | { 8 | private Random _random; 9 | private PartitionDelegate _partitionFunction; 10 | 11 | public delegate int PartitionDelegate(IList list, int left, int right); 12 | 13 | public Quicksort(bool randomPartition) { 14 | if (randomPartition) { 15 | _random = new Random(); 16 | _partitionFunction = PartitionRandom; 17 | } else { 18 | _partitionFunction = PartitionRight; 19 | } 20 | } 21 | 22 | public void Sort(IList list) { 23 | Sort(list, 0, list.Count - 1); 24 | } 25 | 26 | private void Sort(IList list, int left, int right) { 27 | if (left < right) { 28 | int pivot = _partitionFunction(list, left, right); 29 | Sort(list, left, pivot - 1); 30 | Sort(list, pivot + 1, right); 31 | } 32 | } 33 | 34 | private int PartitionRandom(IList list, int left, int right) { 35 | int pivot = left + _random.Next(right - left); 36 | Swap(list, right, pivot); 37 | return PartitionRight(list, left, right); 38 | } 39 | 40 | private int PartitionRight(IList list, int left, int right) { 41 | T pivot = list[right]; 42 | int mid = left; 43 | for (int i = mid; i < right; i++) { 44 | if (list[i].CompareTo(pivot) <= 0) { 45 | Swap(list, i, mid++); 46 | } 47 | } 48 | Swap(list, right, mid); 49 | return mid; 50 | } 51 | 52 | private void Swap(IList list, int a, int b) 53 | { 54 | if (a != b) { 55 | T temp = list[a]; 56 | list[a] = list[b]; 57 | list[b] = temp; 58 | } 59 | } 60 | } 61 | } -------------------------------------------------------------------------------- /src/RadixSort.cs: -------------------------------------------------------------------------------- 1 | namespace GrowingWithTheWeb.Sorting 2 | { 3 | public class RadixSort : IIntegerSortingAlgorithm { 4 | public void Sort(int[] array) { 5 | Sort(array, 10); 6 | } 7 | 8 | public void Sort(int[] array, int radix) { 9 | if (array.Length == 0) { 10 | return; 11 | } 12 | 13 | // Determine minimum and maximum values 14 | int minValue = array[0]; 15 | int maxValue = array[0]; 16 | for (int i = 1; i < array.Length; i++) { 17 | if (array[i] < minValue) { 18 | minValue = array[i]; 19 | } else if (array[i] > maxValue) { 20 | maxValue = array[i]; 21 | } 22 | } 23 | 24 | // Perform counting sort on each exponent/digit, starting at the least 25 | // significant digit 26 | int exponent = 1; 27 | while ((maxValue - minValue) / exponent >= 1) { 28 | CountingSortByDigit(array, radix, exponent, minValue); 29 | exponent *= radix; 30 | } 31 | } 32 | 33 | public void CountingSortByDigit( 34 | int[] array, int radix, int exponent, int minValue) { 35 | int bucketIndex; 36 | int[] buckets = new int[radix]; 37 | int[] output = new int[array.Length]; 38 | 39 | // Initialize bucket 40 | for (int i = 0; i < radix; i++) { 41 | buckets[i] = 0; 42 | } 43 | 44 | // Count frequencies 45 | for (int i = 0; i < array.Length; i++) { 46 | bucketIndex = (int)(((array[i] - minValue) / exponent) % radix); 47 | buckets[bucketIndex]++; 48 | } 49 | 50 | // Compute cumulates 51 | for (int i = 1; i < radix; i++) { 52 | buckets[i] += buckets[i - 1]; 53 | } 54 | 55 | // Move records 56 | for (int i = array.Length - 1; i >= 0; i--) { 57 | bucketIndex = (int)(((array[i] - minValue) / exponent) % radix); 58 | output[--buckets[bucketIndex]] = array[i]; 59 | } 60 | 61 | // Copy back 62 | for (int i = 0; i < array.Length; i++) { 63 | array[i] = output[i]; 64 | } 65 | } 66 | } 67 | } -------------------------------------------------------------------------------- /src/SelectionSort.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace GrowingWithTheWeb.Sorting 5 | { 6 | public class SelectionSort : IGenericSortingAlgorithm where T : IComparable 7 | { 8 | public void Sort(IList list) 9 | { 10 | for (int i = 0; i < list.Count - 1; i++) { 11 | int minIndex = i; 12 | for (int j = i + 1; j < list.Count; j++) { 13 | if (list[j].CompareTo(list[minIndex]) < 0) { 14 | minIndex = j; 15 | } 16 | } 17 | if (minIndex != i) { 18 | Swap(list, i, minIndex); 19 | } 20 | } 21 | } 22 | 23 | private void Swap(IList list, int a, int b) 24 | { 25 | T temp = list[a]; 26 | list[a] = list[b]; 27 | list[b] = temp; 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /test/BaseGenericSortingAlgorithmTest.cs: -------------------------------------------------------------------------------- 1 | using Xunit; 2 | 3 | namespace GrowingWithTheWeb.Sorting 4 | { 5 | public abstract class BaseGenericSortingAlgorithmTest : BaseIntegerSortingAlgorithmTest { 6 | protected IGenericSortingAlgorithm _charSortingAlgorithm; 7 | protected IGenericSortingAlgorithm _stringSortingAlgorithm; 8 | 9 | public BaseGenericSortingAlgorithmTest( 10 | IGenericSortingAlgorithm charSortingAlgorithm, 11 | IGenericSortingAlgorithm stringSortingAlgorithm, 12 | IGenericSortingAlgorithm integerSortingAlgorithm) 13 | : base(new GenericToIntegerSortingAlgorithmAdapter(integerSortingAlgorithm)) { 14 | _charSortingAlgorithm = charSortingAlgorithm; 15 | _stringSortingAlgorithm = stringSortingAlgorithm; 16 | } 17 | 18 | private class GenericToIntegerSortingAlgorithmAdapter : IIntegerSortingAlgorithm { 19 | private IGenericSortingAlgorithm _algorithm; 20 | 21 | public GenericToIntegerSortingAlgorithmAdapter(IGenericSortingAlgorithm algorithm) { 22 | _algorithm = algorithm; 23 | } 24 | 25 | public void Sort(int[] array) 26 | { 27 | _algorithm.Sort(array); 28 | } 29 | } 30 | 31 | [Fact] 32 | public void SortSortedCharArrayTest() { 33 | var result = new char[] {'a','b','c','d','e'}; 34 | _charSortingAlgorithm.Sort(result); 35 | Assert.Equal(new char[] {'a','b','c','d','e'}, result); 36 | } 37 | 38 | [Fact] 39 | public void SortReverseSortedCharArrayTest() { 40 | var result = new char[] {'e','d','c','b','a'}; 41 | _charSortingAlgorithm.Sort(result); 42 | Assert.Equal(new char[] {'a','b','c','d','e'}, result); 43 | } 44 | 45 | [Fact] 46 | public void SortTwoValuesSwappedCharArrayTest() { 47 | var result = new char[] {'a','c','b','d','e'}; 48 | _charSortingAlgorithm.Sort(result); 49 | Assert.Equal(new char[] {'a','b','c','d','e'}, result); 50 | } 51 | 52 | [Fact] 53 | public void SortJumbledCharArrayTest() { 54 | var result = new char[] {'i','b','a','h','c','g','d','f','e','j'}; 55 | _charSortingAlgorithm.Sort(result); 56 | Assert.Equal(new char[] {'a','b','c','d','e','f','g','h','i','j'}, result); 57 | } 58 | 59 | [Fact] 60 | public void SortDuplicateValuesCharArrayTest() { 61 | var result = new char[] {'b','c','a','d','c','a','b','d'}; 62 | _charSortingAlgorithm.Sort(result); 63 | Assert.Equal(new char[] {'a','a','b','b','c','c','d','d'}, result); 64 | } 65 | 66 | [Fact] 67 | public void SortSortingStringArrayTest() { 68 | var result = new string[] {"aa","bb","cc","dd","ee"}; 69 | _stringSortingAlgorithm.Sort(result); 70 | Assert.Equal(new string[] {"aa","bb","cc","dd","ee"}, result); 71 | } 72 | 73 | [Fact] 74 | public void SortReverseSortedStringArrayTest() { 75 | var result = new string[] {"ee","dd","cc","bb","aa"}; 76 | _stringSortingAlgorithm.Sort(result); 77 | Assert.Equal(new string[] {"aa","bb","cc","dd","ee"}, result); 78 | } 79 | 80 | [Fact] 81 | public void SortTwoValuesSwappedStringArrayTest() { 82 | var result = new string[] {"aa","cc","bb","dd","ee"}; 83 | _stringSortingAlgorithm.Sort(result); 84 | Assert.Equal(new string[] {"aa","bb","cc","dd","ee"}, result); 85 | } 86 | 87 | [Fact] 88 | public void SortJumbledStringArrayTest() { 89 | var result = new string[] {"ii","bb","aa","hh","cc","gg","dd","ff","ee","jj"}; 90 | _stringSortingAlgorithm.Sort(result); 91 | Assert.Equal(new string[] {"aa","bb","cc","dd","ee","ff","gg","hh","ii","jj"}, result); 92 | } 93 | 94 | [Fact] 95 | public void SortDuplicateValuesStringArrayTest() { 96 | var result = new string[] {"bb","cc","aa","dd","cc","aa","bb","dd"}; 97 | _stringSortingAlgorithm.Sort(result); 98 | Assert.Equal(new string[] {"aa","aa","bb","bb","cc","cc","dd","dd"}, result); 99 | } 100 | 101 | [Fact] 102 | public void SortSecondCharacterInStringArrayTest() { 103 | var result = new string[] {"bb","ca","ab","da","cb","aa","ba","db"}; 104 | _stringSortingAlgorithm.Sort(result); 105 | Assert.Equal(new string[] {"aa","ab","ba","bb","ca","cb","da","db"}, result); 106 | } 107 | } 108 | } -------------------------------------------------------------------------------- /test/BaseIntegerSortingAlgorithmTest.cs: -------------------------------------------------------------------------------- 1 | using Xunit; 2 | 3 | namespace GrowingWithTheWeb.Sorting 4 | { 5 | public abstract class BaseIntegerSortingAlgorithmTest { 6 | protected IIntegerSortingAlgorithm _integerSortingAlgorithm; 7 | 8 | public BaseIntegerSortingAlgorithmTest(IIntegerSortingAlgorithm algorithm) { 9 | _integerSortingAlgorithm = algorithm; 10 | } 11 | 12 | private void Sort(int[] array) { 13 | _integerSortingAlgorithm.Sort(array); 14 | } 15 | 16 | [Fact] 17 | public void SortEmptyArrayTest() { 18 | var result = new int[] {}; 19 | Sort(result); 20 | Assert.Equal(new int[] {}, result); 21 | } 22 | 23 | [Fact] 24 | public void SortSmallSortedArrayTest() { 25 | var result = new int[] {1,2,3,4,5}; 26 | Sort(result); 27 | Assert.Equal(new int[] {1,2,3,4,5}, result); 28 | } 29 | 30 | [Fact] 31 | public void SortSmallReverseSortedArrayTest() { 32 | var result = new int[] {5,4,3,2,1}; 33 | Sort(result); 34 | Assert.Equal(new int[] {1,2,3,4,5}, result); 35 | } 36 | 37 | [Fact] 38 | public void SortSmallSortedArrayWithOnlyNegativeValuesTest() { 39 | var result = new int[] {-5,-4,-3,-2,-1}; 40 | Sort(result); 41 | Assert.Equal(new int[] {-5,-4,-3,-2,-1}, result); 42 | } 43 | 44 | [Fact] 45 | public void SortSmallReverseSortedArrayWithOnlyNegativeValuesTest() { 46 | var result = new int[] {-1,-2,-3,-4,-5}; 47 | Sort(result); 48 | Assert.Equal(new int[] {-5,-4,-3,-2,-1}, result); 49 | } 50 | 51 | [Fact] 52 | public void SortSmallSortedArrayWithTwoValuesSwappedTest() { 53 | var result = new int[] {1,2,5,4,3}; 54 | Sort(result); 55 | Assert.Equal(new int[] {1,2,3,4,5}, result); 56 | } 57 | 58 | [Fact] 59 | public void SortLargeSortedArrayTest() { 60 | var result = new int[] {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20}; 61 | Sort(result); 62 | Assert.Equal(new int[] {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20}, result); 63 | } 64 | 65 | [Fact] 66 | public void SortLargeReverseSortedArrayTest() { 67 | var result = new int[] {20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0}; 68 | Sort(result); 69 | Assert.Equal(new int[] {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20}, result); 70 | } 71 | 72 | [Fact] 73 | public void SortLargeArrayWithTwoValuesSwappedTest() { 74 | var result = new int[] {0,1,2,8,4,5,6,7,3,9,10,11,12,13,14,15,16,17,18,19,20}; 75 | Sort(result); 76 | Assert.Equal(new int[] {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20}, result); 77 | } 78 | 79 | [Fact] 80 | public void SortLargeSortedArrayWithOnlyNegativeValuesTest() { 81 | var result = new int[] {-20,-19,-18,-17,-16,-15,-14,-13,-12,-11,-10,-9,-8,-7,-6,-5,-4,-3,-2,-1}; 82 | Sort(result); 83 | Assert.Equal(new int[] {-20,-19,-18,-17,-16,-15,-14,-13,-12,-11,-10,-9,-8,-7,-6,-5,-4,-3,-2,-1}, result); 84 | } 85 | 86 | [Fact] 87 | public void SortLargeReverseSortedArrayWithOnlyNegativeValuesTest() { 88 | var result = new int[] {-1,-2,-3,-4,-5,-6,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20}; 89 | Sort(result); 90 | Assert.Equal(new int[] {-20,-19,-18,-17,-16,-15,-14,-13,-12,-11,-10,-9,-8,-7,-6,-5,-4,-3,-2,-1}, result); 91 | } 92 | 93 | [Fact] 94 | public void SortJumbledArrayWithSmallRangeOfValuesTest() { 95 | var result = new int[] {5,-3,2,0,-5,1,4,-4,-2,3,-1}; 96 | Sort(result); 97 | Assert.Equal(new int[] {-5,-4,-3,-2,-1,0,1,2,3,4,5}, result); 98 | } 99 | 100 | [Fact] 101 | public void SortJumbledArrayWithLargeRangeOfValuesTest() { 102 | var result = new int[] {102,10,-50,2938,108,-4011,-38,523,16}; 103 | Sort(result); 104 | Assert.Equal(new int[] {-4011,-50,-38,10,16,102,108,523,2938}, result); 105 | } 106 | 107 | [Fact] 108 | public void SortArrayWithDuplicateValuesTest() { 109 | var result = new int[] {-2,-7,1,9,-7,1,-2,10,-7,-7}; 110 | Sort(result); 111 | Assert.Equal(new int[] {-7,-7,-7,-7,-2,-2,1,1,9,10}, result); 112 | } 113 | } 114 | } -------------------------------------------------------------------------------- /test/BubbleSortOptimisedTest.cs: -------------------------------------------------------------------------------- 1 | namespace GrowingWithTheWeb.Sorting 2 | { 3 | public class BubbleSortOptimisedTest : BaseGenericSortingAlgorithmTest 4 | { 5 | public BubbleSortOptimisedTest() : base( 6 | new BubbleSortOptimised(), 7 | new BubbleSortOptimised(), 8 | new BubbleSortOptimised()) { 9 | } 10 | } 11 | } -------------------------------------------------------------------------------- /test/BubbleSortTest.cs: -------------------------------------------------------------------------------- 1 | namespace GrowingWithTheWeb.Sorting 2 | { 3 | public class BubbleSortTest : BaseGenericSortingAlgorithmTest 4 | { 5 | public BubbleSortTest() : base( 6 | new BubbleSort(), 7 | new BubbleSort(), 8 | new BubbleSort()) { 9 | } 10 | } 11 | } -------------------------------------------------------------------------------- /test/BucketSortTest.cs: -------------------------------------------------------------------------------- 1 | namespace GrowingWithTheWeb.Sorting 2 | { 3 | public class BucketSortTest : BaseIntegerSortingAlgorithmTest 4 | { 5 | public BucketSortTest() : base(new BucketSort()) { 6 | } 7 | } 8 | } -------------------------------------------------------------------------------- /test/CocktailSortTest.cs: -------------------------------------------------------------------------------- 1 | namespace GrowingWithTheWeb.Sorting 2 | { 3 | public class CocktailSortTest : BaseGenericSortingAlgorithmTest 4 | { 5 | public CocktailSortTest() : base( 6 | new CocktailSort(), 7 | new CocktailSort(), 8 | new CocktailSort()) { 9 | } 10 | } 11 | } -------------------------------------------------------------------------------- /test/CombSortTest.cs: -------------------------------------------------------------------------------- 1 | namespace GrowingWithTheWeb.Sorting 2 | { 3 | public class CombSortTest : BaseGenericSortingAlgorithmTest 4 | { 5 | public CombSortTest() : base( 6 | new CombSort(), 7 | new CombSort(), 8 | new CombSort()) { 9 | } 10 | } 11 | } -------------------------------------------------------------------------------- /test/CountingSortTest.cs: -------------------------------------------------------------------------------- 1 | namespace GrowingWithTheWeb.Sorting 2 | { 3 | public class CountingSortTest : BaseIntegerSortingAlgorithmTest 4 | { 5 | public CountingSortTest() : base(new CountingSort()) { 6 | } 7 | } 8 | } -------------------------------------------------------------------------------- /test/GnomeSortTest.cs: -------------------------------------------------------------------------------- 1 | namespace GrowingWithTheWeb.Sorting 2 | { 3 | public class GnomeSortTest : BaseGenericSortingAlgorithmTest 4 | { 5 | public GnomeSortTest() : base( 6 | new GnomeSort(), 7 | new GnomeSort(), 8 | new GnomeSort()) { 9 | } 10 | } 11 | } -------------------------------------------------------------------------------- /test/HeapsortTest.cs: -------------------------------------------------------------------------------- 1 | namespace GrowingWithTheWeb.Sorting 2 | { 3 | public class HeapsortTest : BaseGenericSortingAlgorithmTest 4 | { 5 | public HeapsortTest() : base( 6 | new Heapsort(), 7 | new Heapsort(), 8 | new Heapsort()) { 9 | } 10 | } 11 | } -------------------------------------------------------------------------------- /test/InsertionSortTest.cs: -------------------------------------------------------------------------------- 1 | namespace GrowingWithTheWeb.Sorting 2 | { 3 | public class InsertionSortTest : BaseGenericSortingAlgorithmTest 4 | { 5 | public InsertionSortTest() : base( 6 | new InsertionSort(), 7 | new InsertionSort(), 8 | new InsertionSort()) { 9 | } 10 | } 11 | } -------------------------------------------------------------------------------- /test/MergeSortBottomUpTest.cs: -------------------------------------------------------------------------------- 1 | namespace GrowingWithTheWeb.Sorting 2 | { 3 | public class MergeSortBottomUpTest : BaseGenericSortingAlgorithmTest 4 | { 5 | public MergeSortBottomUpTest() : base( 6 | new MergeSortBottomUp(), 7 | new MergeSortBottomUp(), 8 | new MergeSortBottomUp()) { 9 | } 10 | } 11 | } -------------------------------------------------------------------------------- /test/MergeSortTest.cs: -------------------------------------------------------------------------------- 1 | namespace GrowingWithTheWeb.Sorting 2 | { 3 | public class MergeSortTest : BaseGenericSortingAlgorithmTest 4 | { 5 | public MergeSortTest() : base( 6 | new MergeSort(), 7 | new MergeSort(), 8 | new MergeSort()) { 9 | } 10 | } 11 | } -------------------------------------------------------------------------------- /test/OddEvenSortTest.cs: -------------------------------------------------------------------------------- 1 | namespace GrowingWithTheWeb.Sorting 2 | { 3 | public class OddEvenSortTest : BaseGenericSortingAlgorithmTest 4 | { 5 | public OddEvenSortTest() : base( 6 | new OddEvenSort(), 7 | new OddEvenSort(), 8 | new OddEvenSort()) { 9 | } 10 | } 11 | } -------------------------------------------------------------------------------- /test/Quicksort.cs: -------------------------------------------------------------------------------- 1 | namespace GrowingWithTheWeb.Sorting 2 | { 3 | public class QuicksortRandomPartitionTest : BaseGenericSortingAlgorithmTest 4 | { 5 | public QuicksortRandomPartitionTest() : base( 6 | new Quicksort(true), 7 | new Quicksort(true), 8 | new Quicksort(true)) { 9 | } 10 | } 11 | 12 | public class QuicksortRightPartitionTest : BaseGenericSortingAlgorithmTest 13 | { 14 | public QuicksortRightPartitionTest() : base( 15 | new Quicksort(false), 16 | new Quicksort(false), 17 | new Quicksort(false)) { 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /test/RadixSortTest.cs: -------------------------------------------------------------------------------- 1 | namespace GrowingWithTheWeb.Sorting 2 | { 3 | public class RadixSortTest : BaseIntegerSortingAlgorithmTest 4 | { 5 | public RadixSortTest() : base(new RadixSort()) { 6 | } 7 | } 8 | } -------------------------------------------------------------------------------- /test/SelectionSortTest.cs: -------------------------------------------------------------------------------- 1 | namespace GrowingWithTheWeb.Sorting 2 | { 3 | public class SelectionSortTest : BaseGenericSortingAlgorithmTest 4 | { 5 | public SelectionSortTest() : base( 6 | new SelectionSort(), 7 | new SelectionSort(), 8 | new SelectionSort()) { 9 | } 10 | } 11 | } --------------------------------------------------------------------------------