快速排序其实是逐次对每个基数进行排序,当达到一个临界值(也就是当元素个数达到一定数量时,简单的插入排序速度会大于快排)的时候就用插入排序来进行,其实这也是一个分治处理的过程,和归并思想大同小异,由于归并要进行多次递归,而快排基于基数每次进行线性时间的分组,所以理想情况下快排优于归并。这里就直接上代码。。。
#include <stdio.h>
//当剩余元素数较小时,简单的插入排序速度快于快速排序
#define CutOff 3
//打印数组
void PrintArray(int array[], int size)
{
for(int i = 0; i < size; i++)
{
printf("%d\t", array[i]);
}
printf("\n");
}
//交换连个值
void Swap(int *i, int *j)
{
(*i) = (*i) - (*j);
(*j) = (*i) + (*j);
(*i) = (*j) - (*i);
}
//插入排序
void InsertionSort(int array[], int size)
{
int i, j, temp;
for(i = 1; i < size; i++)
{
temp = array[i];
for(j = i; j > 0 && array[j - 1] > temp; j--)
{
array[j] = array[j - 1];
}
array[j] = temp;
}
}
//获取中值,先把最左边的值作为基准来比较为的是把最小值移到最左边,
//然后把最大值移到最右边,最后交换中值与最右边的值,形成分割雏形
int Median(int array[], int left, int right)
{
int center = (left + right) / 2;
if(array[left] > array[center])
{
Swap(&array[left], &array[center]);
}
if(array[left] > array[right])
{
Swap(&array[left], &array[right]);
}
if(array[center] > array[right])
{
Swap(&array[center], &array[right]);
}
//这么做是为了少一步交换大于中值的步骤
Swap(&array[center], &array[right - 1]);
//返回中值
return array[right - 1];
}
//快速排序的组成部分
void QuickSortComponment(int array[], int left, int right)
{
int leftPos, rightPos, pivot;
if(right - left >= CutOff)
{
pivot = Median(array, left, right);
leftPos = left;
rightPos = right - 1;
while(true)
{
while(array[++leftPos] < pivot){};
while(array[--rightPos] > pivot){};
if(leftPos < rightPos)
{
Swap(&array[leftPos], &array[rightPos]);
}
else
{
break;
}
}
Swap(&array[leftPos], &array[right - 1]);
QuickSortComponment(array, left, leftPos - 1);
QuickSortComponment(array, leftPos + 1, right);
}
else
{
InsertionSort(array + left, right - left + 1);
}
}
//快速排序
void QuickSort(int array[], int size)
{
QuickSortComponment(array, 0, size - 1);
}
int main(void)
{
int array[] = {2, 1, 4, 5, 0, 3, 6, 8, 7, 9};
int size = sizeof(array)/sizeof(array[0]);
QuickSort(array, size);
PrintArray(array, size);
return 0;
}