Algorithm 避免不必要的页面错误。在函数结束时,调用对最左边的分区进行排序,然后对右边的分区进行尾部递归优化,这是一个强有力的论据,但在实践中还不够强大。总是先对最小的分区进行排序,以避免吹扫分区stack@StephanEggermont:如果左分区包含数百万个项目
Algorithm 避免不必要的页面错误。在函数结束时,调用对最左边的分区进行排序,然后对右边的分区进行尾部递归优化,这是一个强有力的论据,但在实践中还不够强大。总是先对最小的分区进行排序,以避免吹扫分区stack@StephanEggermont:如果左分区包含数百万个项目,algorithm,sorting,big-o,quicksort,heapsort,Algorithm,Sorting,Big O,Quicksort,Heapsort,避免不必要的页面错误。在函数结束时,调用对最左边的分区进行排序,然后对右边的分区进行尾部递归优化,这是一个强有力的论据,但在实践中还不够强大。总是先对最小的分区进行排序,以避免吹扫分区stack@StephanEggermont:如果左分区包含数百万个项目,右分区包含两个项目,那么显然应该首先对右分区进行排序。但是,如果左分区的大小不超过右分区的三倍,那么首先对左分区进行排序会有什么问题吗?最坏情况下,堆栈深度会增加,但只会增加一个常数因子,这只会更慢。首先执行左分区或右分区实际上不会影响引用的
避免不必要的页面错误。在函数结束时,调用对最左边的分区进行排序,然后对右边的分区进行尾部递归优化,这是一个强有力的论据,但在实践中还不够强大。总是先对最小的分区进行排序,以避免吹扫分区stack@StephanEggermont:如果左分区包含数百万个项目,右分区包含两个项目,那么显然应该首先对右分区进行排序。但是,如果左分区的大小不超过右分区的三倍,那么首先对左分区进行排序会有什么问题吗?最坏情况下,堆栈深度会增加,但只会增加一个常数因子,这只会更慢。首先执行左分区或右分区实际上不会影响引用的局部性最坏的情况发生在元素已经排序时——这是一种相对罕见的情况——如果系统中可能出现这种情况,则可以通过先执行简单的无序排列来轻松避免这种情况。引用的局部性是QR快速运行时性能的关键。@Paul Simple shuffle无法解决快速排序数组中重复值的问题。
static void Main(string[] args)
{
int[] arrToSort = new int[100000000];
var r = new Random();
for (int i = 0; i < arrToSort.Length; i++) arrToSort[i] = r.Next(1, arrToSort.Length);
Console.WriteLine("Press q to quick sort, s to Array.Sort");
while (true)
{
var k = Console.ReadKey(true);
if (k.KeyChar == 'q')
{
// quick sort
Console.WriteLine("Beg quick sort at " + DateTime.Now.ToString("HH:mm:ss.ffffff"));
QuickSort(arrToSort, 0, arrToSort.Length - 1);
Console.WriteLine("End quick sort at " + DateTime.Now.ToString("HH:mm:ss.ffffff"));
for (int i = 0; i < arrToSort.Length; i++) arrToSort[i] = r.Next(1, arrToSort.Length);
}
else if (k.KeyChar == 's')
{
Console.WriteLine("Beg Array.Sort at " + DateTime.Now.ToString("HH:mm:ss.ffffff"));
Array.Sort(arrToSort);
Console.WriteLine("End Array.Sort at " + DateTime.Now.ToString("HH:mm:ss.ffffff"));
for (int i = 0; i < arrToSort.Length; i++) arrToSort[i] = r.Next(1, arrToSort.Length);
}
}
}
static public void QuickSort(int[] arr, int left, int right)
{
int begin = left
, end = right
, pivot
// get middle element pivot
//= arr[(left + right) / 2]
;
//improved pivot
int middle = (left + right) / 2;
int
LM = arr[left].CompareTo(arr[middle])
, MR = arr[middle].CompareTo(arr[right])
, LR = arr[left].CompareTo(arr[right])
;
if (-1 * LM == LR)
pivot = arr[left];
else
if (MR == -1 * LR)
pivot = arr[right];
else
pivot = arr[middle];
do
{
while (arr[left] < pivot) left++;
while (arr[right] > pivot) right--;
if(left <= right)
{
int temp = arr[right];
arr[right] = arr[left];
arr[left] = temp;
left++;
right--;
}
} while (left <= right);
if (left < end) QuickSort(arr, left, end);
if (begin < right) QuickSort(arr, begin, right);
}