Quick sort是效率不错的一种排序算法,效率上和插入排序、冒泡排序的关系是: >(优于)
快速排序 > 插入排序 > 冒泡排序。
快速排序里面已经有了分治的策略,实现快速排序的核心就是拆分任务、递归。
一个子任务就是:任取数组中的一个数值,将所有的小于该值的数据放到该值的左侧,所有大于等于该值的数据放到该值的右边。
在实现的时候我觉得只需要前半句就行:将所有的小于该值的数据放到该值的左侧。因为这样右侧的一定是后半句。
在开始我实现了一个很锉的快速排序,因为我同时考虑前后半句。我能想到的最直接的办法就是直接重新new两个同样大小的数组,
逐个比较数组中的数据和基准点数据,小于则放到smaller数组里,大于则放到bigger数组里,然后再拷贝回原数组。
测试的结果是正确的,在10000大小的数组中,效率落后于插入排序,甚至不如冒泡排序,所花时间是插入排序的2倍。
快速排序 > 插入排序 > 冒泡排序。
快速排序里面已经有了分治的策略,实现快速排序的核心就是拆分任务、递归。
一个子任务就是:任取数组中的一个数值,将所有的小于该值的数据放到该值的左侧,所有大于等于该值的数据放到该值的右边。
在实现的时候我觉得只需要前半句就行:将所有的小于该值的数据放到该值的左侧。因为这样右侧的一定是后半句。
在开始我实现了一个很锉的快速排序,因为我同时考虑前后半句。我能想到的最直接的办法就是直接重新new两个同样大小的数组,
逐个比较数组中的数据和基准点数据,小于则放到smaller数组里,大于则放到bigger数组里,然后再拷贝回原数组。
测试的结果是正确的,在10000大小的数组中,效率落后于插入排序,甚至不如冒泡排序,所花时间是插入排序的2倍。
代码如下:
template<class T>
static int Partition(int size, T * list)
{
int pivot = 0;
T pivotValue = list[pivot];
int smallerIndex = 0;
int biggerIndex = 0;
T *biggers = new T[size];
T *smallers = new T[size];
memset((void*)biggers, 0, sizeof(T)*size);
memset((void*)smallers, 0, sizeof(T)*size);
smallerIndex = 0;
biggerIndex = 0;
for (int i = 1; i<size; ++i)
{
if (list[i] > pivotValue)
{
biggers[biggerIndex] = list[i];
++biggerIndex;
}
else
{
smallers[smallerIndex] = list[i];
++smallerIndex;
}
}
smallers[smallerIndex] = pivotValue;
++smallerIndex;
memcpy((void*)list, (void*)smallers, sizeof(T)*(smallerIndex));
T * pDest = list + smallerIndex;
memcpy((void*)pDest, (void*)biggers, sizeof(T)*(size - smallerIndex));
delete[] smallers;
delete[] biggers;
biggers = NULL;
smallers = NULL;
return smallerIndex;
}
template<class T>
static void QuickSort(T *list, int size)
{
if (size <= 1)
return;
int smallerSize = Partition(size, list);
QuickSort(list, smallerSize);
QuickSort(list + smallerSize, size - smallerSize);
}
static void QuickSortTest()
{
const int size = SortDefaultSize;
int list[size] = { 0 };
FillRandomValue(list, SortDefaultSize);
//int list[8] = {34, 12, 0, 77, 63, 13, 16, 23};
PrintArray(list, size);
Performance *pPerformance = new Performance("QuickSort");
QuickSort(list, size);
delete pPerformance;
PrintArray(list, size);
}
后来仔细的阅读了维基百科上的快排,发现有一种原地快速排序,就如我所说的只需要关注前半句,实现了前半句,后半句自然实现了。
而却原地排序所需要的辅助内存要远远小于每次new的内存,上面的排序时间都花在分配和释放内存了。下面的是一个效率不错的快排:
template<class T>
static size_t Partition(T *list, size_t size)
{
size_t pivot = 0;
T pivotValue = list[pivot];
Swap(list[pivot], list[size - 1]);
int index = 0;
for (size_t i = 0; i < size; ++i)
{
if (list[i] < pivotValue)
{
Swap(list[index], list[i]);
++index;
}
}
Swap(list[size - 1], list[index]);
return index;
}
template<class T>
static void QuickSortInPlace(T *list, size_t size)
{
if (size <= 1) return;
size_t pivot = Partition(list, size);
QuickSortInPlace(list, pivot);
QuickSortInPlace(list + pivot + 1, size - pivot - 1);
}
static void QuickSortInPlaceTest()
{
const int size = SortDefaultSize;
int list[size] = { 0 };
FillRandomValue(list, size);
PrintArray(list, size);
Performance *pPerformance = new Performance("QuickSort-InPlace");
QuickSortInPlace(list, size);
delete pPerformance;
PrintArray(list, size);
}
http://www.cnblogs.com/butyoux/archive/2013/01/16/2863152.html