Here I've prepared my solutions for the following algorithms, and was curious if there were a way to optimize any of them. Any input is welcome and appreciated!
using System; using System.Collections.Generic; using System.Linq; namespace algotest { class Program { static void InsertionSort(int[] arr) { for (int i = 1; i < arr.Length; ++i) { int temp = arr[i]; bool sorted = false; for (int j = i - 1; j >= 0 && !sorted;) { if (temp < arr[j]) { arr[j + 1] = arr[j]; --j; arr[j + 1] = temp; } else { sorted = true; } } } } static void BubbleSort(int[] arr) { int temp = 0; for (int i = 0; i < arr.Length; ++i) { for (int j = 0; j < arr.Length - 1; ++j) { if (arr[j] > arr[j + 1]) { temp = arr[j + 1]; arr[j + 1] = arr[j]; arr[j] = temp; } } } } static void SelectionSort(int[] arr) { int temp, min; for (int i = 0; i < arr.Length - 1; ++i) { min = i; for (int j = i + 1; j < arr.Length; ++j) { if (arr[j] < arr[min]) { min = j; } } temp = arr[min]; arr[min] = arr[i]; arr[i] = temp; } } static void Merge(int[] arr, int left, int pivot, int right) { int[] temp = new int[25]; int index = left; int leftBound = pivot - 1; int length = right - left + 1; while (left <= leftBound && pivot <= right) { if (arr[left] <= arr[pivot]) { temp[index++] = arr[left++]; } else { temp[index++] = arr[pivot++]; } } while (left <= leftBound) { temp[index++] = arr[left++]; } while (pivot <= right) { temp[index++] = arr[pivot++]; } for (int i = 0; i < length; i++) { arr[right] = temp[right]; right--; } } static void MergeSort(int[] arr, int left, int right) { if (right > left) { int pivot = (right + left) / 2; MergeSort(arr, left, pivot); MergeSort(arr, pivot + 1, right); Merge(arr, left, pivot + 1, right); } } static void QuickSort(int[] arr, int left, int right) { int i = left, j = right; int pivot = arr[(left + right) / 2]; while (i <= j) { while (arr[i].CompareTo(pivot) < 0) { ++i; } while (arr[j].CompareTo(pivot) > 0) { --j; } if (i <= j) { int temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; ++i; --j; } } if (left < j) { QuickSort(arr, left, j); } if (i < right) { QuickSort(arr, i, right); } } static void Heapify(int[] arr, int i, int n) { try { int temp = arr[i]; int j = 2 * i; while (j <= n) { if (j < n && arr[j] < arr[j + 1]) { j++; } if (temp >= arr[j]) { break; } arr[j / 2] = arr[j]; j *= 2; } arr[j / 2] = temp; } catch (IndexOutOfRangeException err) { Console.WriteLine("Array Out of Bounds ", err); } } static void HeapSort(int[] arr) { for (int i = arr.Length / 2; i >= 0; --i) { Heapify(arr, i, arr.Length - 1); } for (int i = arr.Length - 2; i >= 0; --i) { int temp = arr[i + 1]; arr[i + 1] = arr[0]; arr[0] = temp; Heapify(arr, 0, i); } } static void CountingSort(int[] arr) { int[] count = new int[arr.Max() + 1]; for (int i = 0; i < arr.Length; ++i) { ++count[arr[i]]; } int j = 0; for (int i = 0; i < count.Length; ++i) { for (int k = 0; k < count[i]; ++k) { arr[j++] = i; } } } static void RadixSort(int[] arr) { int i, j; int[] temp = new int[arr.Length]; for (int shift = 31; shift > -1; --shift) { j = 0; for (i = 0; i < arr.Length; ++i) { bool move = (arr[i] << shift) >= 0; if (shift == 0 ? !move : move) { arr[i - j] = arr[i]; } else { temp[j++] = arr[i]; } } Array.Copy(temp, 0, arr, arr.Length - j, j); } } static void BucketSort(int[] arr) { // bucket size key: // array 1-99 ; 10 buckets // arrat 100-199 ; 20 buckets // etc. // TODO: Implement logic to determine bucket size? int numOfBuckets = 10; List<int> result = new List<int>(); List<int>[] buckets = new List<int>[numOfBuckets]; for (int i = 0; i < numOfBuckets; ++i) { buckets[i] = new List<int>(); } for (int i = 0; i < arr.Length; ++i) { int index = arr[i] / numOfBuckets; buckets[index].Add(arr[i]); } for (int i = 0; i < numOfBuckets; ++i) { int[] temp = buckets[i].ToArray(); InsertionSort(arr); result.AddRange(temp); } arr = result.ToArray(); } static void Main(string[] args) { Console.WriteLine("Please select an algorithm: "); Console.WriteLine("I : InsertionSort O(n^2)"); Console.WriteLine("B : BubbleSort O(n^2)"); Console.WriteLine("S : SelectionSort O(n^2)"); Console.WriteLine("M : MergeSort O(nlgn)"); Console.WriteLine("Q : QuickSort O(nlgn)"); Console.WriteLine("H : HeapSort O(nlgn)"); Console.WriteLine("C : CountingSort O(n)"); Console.WriteLine("R : RadixSort O(n)"); Console.WriteLine("U : BucketSort O(n)"); string algorithm = Console.ReadLine().ToUpper(); Console.WriteLine("How many elements?"); int numOfElements = int.Parse(Console.ReadLine()); int[] arr = new int[numOfElements]; Random rand = new Random(); Console.WriteLine("Generating random data..."); for (int i = 0; i < numOfElements; ++i) { arr[i] = rand.Next(100); } switch (algorithm) { case "I": InsertionSort(arr); break; case "B": BubbleSort(arr); break; case "S": SelectionSort(arr); break; case "M": MergeSort(arr, 0, arr.Length - 1); break; case "Q": QuickSort(arr, 0, arr.Length - 1); break; case "H": HeapSort(arr); break; case "C": CountingSort(arr); break; case "R": RadixSort(arr); break; case "U": BucketSort(arr); break; } for (int i = 0; i < arr.Length; ++i) { Console.WriteLine(arr[i]); } Console.WriteLine("Press any key to exit."); Console.ReadKey(); } } }
optimize
(goal?). Have ordered items at both ends with insertion sort to almost half the number of assignments (first step towards Library_sort). Select min and max concurrently in selection sort, comparing only the lesser of each pair of input items to min, the greater to max to save one fourth on comparisons. (Next step is to keep pairs ordered to avoid the next quarter: first step to Heapsort.) Annoyingly effective: "bubbling up" candidates. Iterate on quicksort's larger partition.\$\endgroup\$