1、原理
(2)将大于或等于分界值的数据集中到数组右边,小于分界值的数据集中到数组的左边。
(3)左边和右边的数据可以独立排序。对于左侧的数组数据,又可以取一个分界值,将该部分数据分成左右两部分,同样在左边放置较小值,右边放置较大值。右侧的数组数据也可以做类似处理
2、递归实现
void QuickSort(int* a, int left, int right)
{
if (left >= right)//递归结束条件
return;
int begin = left;
int end = right;
int key = left;//取最左边的值为基准值
while (left < right)
{
//右边先走,遇到小于key的值时停止
while (left < right && a[right] >= a[key])
right--;
//遇到大于key的值时停止
while (left < right&& a[left] <= a[key])
left++;
Swap(&a[left], &a[right]);
}
//交换相遇位置与key
Swap(&a[left], &a[key]);
//key移动到了中间
key = left;
//begin key end
//递归
QuickSort(a, begin, key - 1);
QuickSort(a, key + 1,end);
3.优化
当key最接近所有数据的中间值时,效率最高。而key太大或太小时,效率相对较低
这里采用三数取中的方法
//三数取中
//找出最左值,最右值,中间值中的mid
int GetMidNumi(int* a, int left, int right)
{
int mid = (left + right) / 2;
if (a[left] < a[mid])
{
if (a[mid] < a[right])
{
return mid;
}
else if (a[left] > a[right])
{
return left;
}
else
{
return right;
}
}
else// a[left]>a[mid]
{
if (a[mid] > a[right])
{
return mid;
}
else if (a[left] < a[right])
{
return left;
}
else
{
return right;
}
}
}
void QuickSort1(int* a, int left, int right)
{
if (left >= right)
return;
int begin = left;
int end = right;
//三数取中(找的是下标)
int midi = GetMidNumi(a, left, right);
if (midi != left)
Swap(&a[midi], &a[left]);
int key = left;
while (left < right)
{
while (left < right && a[right] >= a[key])
right--;
while (left < right&& a[left] <= a[key])
left++;
Swap(&a[left], &a[right]);
}
Swap(&a[left], &a[key]);
key = left;
QuickSort1(a, begin, key - 1);
QuickSort1(a, key + 1,end);
}
4.非递归实现
用栈实现(数字为数组元素下标)
将数字0和9入栈
将0和9出栈,先入栈6和9,再入栈0和4
出栈0和4,入栈3和4,再入栈0和1
当区间只有一个值或者没有值时,不再入栈,,如此排序完所有区间
//需要栈的相关代码,这里就不给出了
// 快速排序 非递归实现
void QuickSortNonR(int* a, int left, int right)
{
//栈的初始化
ST st;
STInit(&st);
//入栈
STPush(&st, right);
STPush(&st, left);
//当栈中无元素时就停止循环
while (!STEmpty(&st))
{
//取栈顶元素
int begin = STTop(&st);
//出栈
STPop(&st);
int end = STTop(&st);
STPop(&st);
//单趟排序
int key = QuickSort(a, begin, end);
if (key + 1 < end)//判断是否需要继续入栈。下同
{
STPush(&st, end);
STPush(&st, key + 1);
}
if (key > begin + 1)
{
STPush(&st, key-1);
STPush(&st, begin);
}
}
STDestroy(&st);
}