快速排序基本可以分为两种:递归和非递归法。又可以将区间按照基准值划分为左右两半部分进行排序,排序方法有hoare版(左右指针法)、挖坑法、前后指针法。好话不多说,上代码。
递归
快排的递归方法
```
void Quicksort(int *arr, int left, int right)
{
if (right - left > 1)
{
int div = Partion(arr, left, right);
Quicksort(arr, left, div-1);
Quicksort(arr, div+1, right);
}
}
```
hoare版(左右指针法)
首先选一个key为基准,建立一个begin=left、end=right,如果begin小于key,则begin++,如果end大于key,则end--,当begin大于key的值,而end小于key的值时,对两个数的位置进行交换,当begin遇到end时,将基准值和begin进行交换
int Partion(int* arr, int left, int right)
{
int mid = GetMidIndex(arr, left, right);
if (mid != right)
swap(&arr[mid], &arr[right]);
int begin = left;
int end = right;
int key = arr[right];
while (begin < end)
{
while (begin < end && arr[begin] <= key)
begin++;
while (begin < end && arr[end] >= key)
end--;
if (begin < end)
{
swap(&arr[begin], &arr[end]);
}
}
swap(&arr[right], &arr[begin]);
return begin;
}
挖坑法
首先选取一个key值,设置两个变量begin = left ,end = right,从left一直向后走,直到找到一个大于key的值,然后将该数放入坑中,坑位变成了array[begin],right一直向前走,直到找到一个小于key的值,然后将该数放入坑中,坑位变成了array[end]。
重复3和4的步骤,直到left和right相遇,然后将key放入最后一个坑位。
int Partion2(int* arr, int left, int right)
{
int mid = GetMidIndex(arr, left, right);
if (mid != right)
swap(&arr[mid], &arr[right]);
int begin = left;
int end = right;
int key = arr[right];
while (begin < end)
{
while (begin < end && arr[begin] <= key)
begin++;
arr[end] = arr[begin];
while (begin < end && arr[end] >= key)
end--;
arr[begin] = arr[end];
}
arr[end] = key;
return begin;
}
前后指针法
定义变量cur指向序列的开头,定义变量pre指向cur的前一个位置。当array[cur] < key时,cur和pre同时往后走,如果array[cur]>key,cur往后走,pre留在大于key的数值前一个位置。当array[cur]再次 < key时,交换array[cur]和array[pre]。
在没找到大于key值前,pre永远紧跟cur,遇到大的两者之间机会拉开差距,中间差的肯定是连续的大于key的值,当再次遇到小于key的值时,交换两个下标对应的值就好了
int Partion3(int* arr, int left, int right)
{
int mid = GetMidIndex(arr,left,right);
if (mid != right)
swap(&arr[mid], &arr[right]);
int key = arr[right];
int cur = left;
int pre = cur - 1;
while (cur < right){
if(arr[cur] <= key && ++pre != cur){
swap(&arr[cur], &arr[pre]);
}
++cur;
}
if (++pre != cur && pre != right)
swap(&arr[pre], &arr[right]);
return pre;
}
非递归
递归转化为非递归就是压栈
void QuickSortNor(int *arr, int left, int right)
{
stack<int> s;
s.push(left);
s.push(right);
while (s.empty()){
int right = s.top();
s.pop();
int left = s.top();
s.pop();
int Index = Partion(arr, left, right);
if (Index - 1 > left)
{
s.push(left);
s.push(Index - 1);
}
if (Index + 1 < right)
{
s.push(Index + 1);
s.push(right);
}
}
}