Sorting algorithms/Quicksort: Difference between revisions
Content added Content deleted
m ({{out}}) |
|||
Line 773: | Line 773: | ||
}</lang> |
}</lang> |
||
=={{header|C sharp|C#}}== |
=={{header|C sharp|C#}}== |
||
Note that |
Note that Array.Sort and ArrayList.Sort both use an unstable implementation of the quicksort algorithm. |
||
<lang csharp> |
<lang csharp>namespace Sort { |
||
using System |
using System; |
||
static class QuickSort<T> where T : IComparable { |
|||
namespace QuickSort |
|||
#region Constants |
|||
{ |
|||
private const Int32 insertionLimitDefault = 32; |
|||
class Program |
|||
private const Int32 pivotSamples = 5; |
|||
{ |
|||
#endregion |
|||
static void Main(string[] args) |
|||
{ |
|||
List<int> unsorted = new List<int> { 1, 3, 5, 7, 9, 8, 6, 4, 2 }; |
|||
List<int> sorted = quicksort(unsorted); |
|||
#region Properties |
|||
Console.WriteLine(string.Join(",", sorted)); |
|||
public static Int32 InsertionLimit { get; set; } |
|||
Console.ReadKey(); |
|||
private static Random Random { get; set; } |
|||
#endregion |
|||
#region Constructors |
|||
static QuickSort() { |
|||
InsertionLimit = insertionLimitDefault; |
|||
Random = new Random(); |
|||
} |
|||
#endregion |
|||
#region Sort Methods |
|||
public static void Sort(T[] entries) { |
|||
Sort(entries, 0, entries.Length - 1); |
|||
} |
|||
public static void Sort(T[] entries, Int32 first, Int32 last) { |
|||
var length = last + 1 - first; |
|||
while (length > 1) { // Tail recurse over longer partition |
|||
if (length < InsertionLimit) { |
|||
InsertionSort<T>.Sort(entries, first, last); |
|||
return; |
|||
} |
} |
||
var median = pivot(entries, first, last); |
|||
{ |
|||
var left = first; |
|||
List<int> loe = new List<int>(), gt = new List<int>(); |
|||
var right = last; |
|||
partition(entries, median, ref left, ref right); |
|||
int pivot = arr.Count / 2; |
|||
var leftLength = right + 1 - first; |
|||
var rightLength = last + 1 - left; |
|||
foreach (int i in arr) |
|||
{ |
if (leftLength < rightLength) { |
||
Sort(entries, first, right); |
|||
first = left; |
|||
length = rightLength; |
|||
} |
|||
gt.Add(i); |
|||
else { |
|||
Sort(entries, left, last); |
|||
last = right; |
|||
length = leftLength; |
|||
} |
|||
} |
|||
loe.Add(pivot_val); |
|||
} |
|||
gt.Add(pivot_val); |
|||
private static T pivot(T[] entries, Int32 first, Int32 last) { |
|||
} |
|||
var length = last + 1 - first; |
|||
var sampleSize = Math.Min(pivotSamples, length); |
|||
return resultSet; |
|||
var right = first + sampleSize - 1; |
|||
for (var left = first; left <= right; left++) { |
|||
// Random sampling avoids pathological cases |
|||
var random = Random.Next(left, last + 1); |
|||
// Sample without replacement |
|||
if (left != random) |
|||
Swap(entries, left, random); |
|||
} |
|||
InsertionSort<T>.Sort(entries, first, right); |
|||
return entries[first + sampleSize / 2]; |
|||
} |
|||
private static void partition(T[] entries, T pivot, ref Int32 left, ref Int32 right) { |
|||
while (left <= right) { |
|||
while (pivot.CompareTo(entries[left]) > 0) |
|||
left++; // pivot follows entry |
|||
while (pivot.CompareTo(entries[right]) < 0) |
|||
right--; // pivot precedes entry |
|||
if (left < right) // Move entries to their correct partition |
|||
Swap(entries, left++, right--); |
|||
else if (left == right) { // No swap needed |
|||
left++; |
|||
right--; |
|||
} |
|||
} |
|||
} |
|||
internal static void Swap(T[] entries, Int32 index1, Int32 index2) { |
|||
var entry = entries[index1]; |
|||
entries[index1] = entries[index2]; |
|||
entries[index2] = entry; |
|||
} |
|||
#endregion |
|||
#region Insertion Sort |
|||
static class InsertionSort<T> where T : IComparable { |
|||
public static void Sort(T[] entries, Int32 first, Int32 last) { |
|||
for (var i = first + 1; i <= last; i++) { |
|||
var insert = entries[i]; |
|||
var j = i; |
|||
while (j > first && entries[j - 1].CompareTo(insert) > 0) |
|||
entries[j] = entries[--j]; |
|||
entries[j] = insert; |
|||
} |
} |
||
} |
|||
} |
} |
||
#endregion |
|||
} |
|||
}</lang> |
}</lang> |
||