public static int QuickSort <T>(this T[] arr, PivotChoice choice = PivotChoice.ChooseRandom) where T : IComparable <T> { ChoosePivotIndex <T> pivotIntFunc = CalcMedium; switch (choice) { case PivotChoice.AlwaysFirst: pivotIntFunc = (T[] ar, int left, int right) => left; break; case PivotChoice.AlwaysLast: pivotIntFunc = (T[] ar, int left, int right) => right; break; case PivotChoice.CalcMedium: pivotIntFunc = CalcMedium; break; case PivotChoice.ChooseRandom: Random rnd = new Random(); pivotIntFunc = (T[] ar, int left, int right) => rnd.Next(left, right + 1); break; } return(Sort <T>(arr, 0, arr.Length - 1, pivotIntFunc)); }
private static int FindPivot(int[] elements, int left, int right, PivotChoice choice) { if (choice == PivotChoice.Random) { Random random = new Random(); return elements[random.Next(left, right)]; } else if (choice == PivotChoice.Left) return elements[left]; else if (choice == PivotChoice.Right) return elements[right]; else return elements[(left + right) / 2]; }
/// <summary> /// Recursively quick sorts unsorted array of integers /// </summary> /// <param name="elements">unsorted array of integers</param> /// <param name="left">left most index</param> /// <param name="right">right most index</param> /// <param name="choice">how pivot should be chosen</param> /// <returns></returns> private static int[] Sort(int[] elements, int left, int right, PivotChoice choice) { //set i to left most index int i = left; //set j to right most index int j = right; //create tmp for swapping int tmp; //set the pivot element to the middle element int pivot = FindPivot(elements, left, right, choice); //increment i, decrement j until i <= j (hit each other) while (i <= j) { //increment the left side index while the elements at that index are less than the pivot while (elements[i] < pivot) i++; //decrement the right side index whiel the elements at that index are greater than the pivot while (elements[j] > pivot) j--; //when the i element value and the j element value are on the wrong sides of the pivot element value, check that they didn't hit each other if(i <= j) { //if i and j didn't overtake each other, swap the i element and j element tmp = elements[i]; elements[i] = elements[j]; elements[j] = tmp; i++; j--; } } //if the j decremented index is greater than the left most index, recursively sort that partitioned array if(left < j) Sort(elements, left, j, choice); //if the i incremented index is less than the right most index, recursively sort that partitioned array if (i < right) Sort(elements, i, right, choice); return elements; }
/// <summary> /// Quick sorts array of integers /// </summary> /// <param name="elements">Unsorted array of integers</param> /// <returns>Sorted array of integers</returns> public static int[] Sort(int[] elements, PivotChoice choice = PivotChoice.Half) { //call private sort method providing, elements, left and a right indexes return Sort(elements, 0, elements.Length - 1, choice); }