void SelectSort(int* a, int n)
{
int begin = 0;
end = n - 1;
while (begin < end)
{
int mini = begin, maxi = begin;
for (int i = begin; i <= end; i++)
{
if (a[i] > a[maxi])
{
maxi = i;
}
if (a[i] < a[mini])
{
mini = i;
}
}
if (begin == maxi)
{
maxi = mini;
}
swap(&a[mini], &a[begin]);
swap(&a[maxi], &a[end]);
++begin;
--end;
}
}
int _QuickSort(int* a, int left, int right)
{
int begin = left;
int end = right;
int keyi = left;
++left;
while (left <= right)
{
// right从右往左找基准值⼩的
while (left <= right && a[right] > a[keyi])
{
--right;
}
// left从左往右找基准值大的
while (left <= right && a[left] < a[keyi])
{
++left;
}
if (left <= right)
{
swap(&a[left++], &a[right--]);
}
}
swap(&a[keyi], &a[right]);
return right;
}
int _QuickSort(int* a, int left, int right)
{
int mid = a[left];
int hole = left;
int key = a[hole];
while (left < right)
{
while (left < right && a[right] >= key)
{
--right;
}
a[hole] = a[right];
hole = right;
while (left < right && a[left] <= key)
{
++left;
}
a[hole] = a[left];
hole = left;
}
a[hole] = key;
return hole;
}
2.3、lomuto前后指针
创建前后指针,从左往右找⽐基准值⼩的进⾏交换,使得⼩的都排在基准值的左边。
初始时,prev指针指向序列开头, cur指针指向prev指针的后一个位置
创建两个变量prev,cur,cur从左往右找比基准值要小的数据,prev和cur交换
cur探路,找比基准值要小的数据
cur找到了比基准值小的数据:++prev,prev和cur交换,cur++
cur未找到比基准值小的数据:cur++
复制代码
int _QuickSort(int* a, int left, int right)
{
int prev = left;
cur = left + 1;
int key = left;
while (cur <= right)
{
if (a[cur] < a[key] && ++prev != cur)
{
swap(&a[cur], &a[prev]);
}
++cur;
}
swap(&a[key], &a[prev]);
return prev;
}
时间复杂度: O(nlogn)
空间复杂度: O(logn)
3、非递归快速排序
⾮递归版本的快速排序需要借助数据结构:栈
复制代码
-----默认可以使用栈和栈相关算法-----
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);
// 单趟 - [begin,end]找基准值
int keyi = begin;
int prev = begin;
int cur = begin + 1;
while (cur <= end)
{
if (a[cur] < a[keyi] && ++prev != cur)
Swap(&a[prev], &a[cur]);
++cur;
}
Swap(&a[keyi], &a[prev]);
keyi = prev;
// begin keyi end
// 左序列:[begin, keyi-1] 右序列:keyi [keyi+1, end]
if (keyi + 1 < end)
{
STPush(&st, end);
STPush(&st, keyi + 1);
}
if (begin < keyi-1)
{
STPush(&st, keyi-1);
STPush(&st, begin);
}
}
STDestroy(&st);
}