forked from iiitv/algos
-
Notifications
You must be signed in to change notification settings - Fork 0
/
QuickSort.cs
110 lines (100 loc) · 3.49 KB
/
QuickSort.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
/*
Time Complexity: Best: O(n log(n)), Average: O(n log(n)), Worst: O(n^2)
Space Complexity: O(log(n))
*/
using System;
public class QuickSort
{
/// <summary>
/// Chooses a pivot based on the median of three values in the array (start, mid, end - 1).
/// Pivot is placed at the beginning of the array.
/// </summary>
/// <param name="a">The array</param>
/// <param name="start">The start pivoting position in the array</param>
/// <param name="end">The end pivoting position in the array</param>
public static void ChoosePivot(int[] a, int start, int end)
{
int mid = start + (end - start) / 2;
int median = Math.Max(Math.Min(a[start], a[mid]), Math.Min(Math.Max(a[start], a[mid]), a[end - 1]));
int pivotPos = Array.IndexOf(a, median);
Swap(a, pivotPos, start);
}
/// <summary>
/// Partitions an array into two parts based on a pivot.
/// All values smaller than the pivot will be placed before the pivot in the array.
/// All values grater than the pivot will be placed after the pivot in the array
/// </summary>
/// <param name="a">The array</param>
/// <param name="start">The start pivoting position in the array</param>
/// <param name="end">The end pivoting position in the array</param>
/// <returns>The new position of the pivot in the array</returns>
public static int Partition(int[] a, int start, int end)
{
int pivotPos = start; //pivot position (index in the array)
int pivotVal = a[pivotPos]; //the value of the pivot
int bigStart = start + 1; //start index of all values greater than the pivot
for (int curr = start + 1; curr < end; curr++)
{
if (a[curr] < pivotVal)
{
Swap(a, curr, bigStart);
bigStart++;
}
}
Swap(a, pivotPos, bigStart - 1);
pivotPos = bigStart - 1;
return pivotPos;
}
/// <summary>
/// Sorts an array using the Quick Sort algorithm
/// </summary>
/// <param name="a">The array to sort</param>
/// <param name="start">The start sorting position in the array</param>
/// <param name="end">The end sorting position in the array</param>
public static void DoQuickSort(int[] a, int start, int end)
{
if(end - start == 2)
{
if(a[start] > a[end - 1])
Swap(a, start, end - 1);
}
else if(end - start > 1)
{
ChoosePivot(a, start, end);
int pivotPos = Partition(a, start, end);
DoQuickSort(a, start, pivotPos);
DoQuickSort(a, pivotPos + 1, end);
}
}
/// <summary>
/// Quick Sort helper method
/// </summary>
/// <param name="a">The array to sort</param>
public static void DoQuickSort(int[] a)
{
if (a != null && a.Length > 1)
DoQuickSort(a, 0, a.Length);
}
/// <summary>
/// Swap two index positions in an array
/// </summary>
/// <param name="a">The array</param>
/// <param name="x">The first index</param>
/// <param name="mid">The second index</param>
public static void Swap(int[] a, int x, int y)
{
int temp = a[x];
a[x] = a[y];
a[y] = temp;
}
public static void Main()
{
int[] arr = new int[] {2, 4, 2, 6, 7, -1};
DoQuickSort(arr);
foreach(int element in arr)
{
Console.Write(element + " ");
}
Console.WriteLine("");
}
}