大家都知道快速排序是排序中综合性和使用场景最好的,也正是因为如此,今天我就给大家说一下快速排序吧。
快速排序是Hoare于1962年提出的一种二叉树结构的交换排序方法
基本操作:
1.任取待排序元素序列中的某元素作为基准值
2.按照该排序码将待排序集合分割成两子序列,左子序列中所有元素均小于基准值,右子序列中所有元素均大于基准值。
3.整个待排序区间分为三个部分:比基准值小[left,pivotIndex - 1]、基准值[pivotIndex]、比基准值大[pivotIndex + 1,right]
4.然后最左右子序列重复该过程,直到区间内元素个数为0或者为1。
将区间按照基准值划分为左右两半部分的常见方式有:
1.hoare法
2.挖坑法
3.前后指针法
基准值的选择:一般情况下我们选取待排序的最后一位元素作为基准值,但是当基准值的选取接近最值或等于最值是会造成左右序列元素个数相差巨大,效率降低。
所以我们还会采用下面三种方法:
1.取最边上的数
2.三数取中法
3.随机法
1.快速排序之递归算法
首先我们知道上面将区间按照基准值划分时,它们选取基准值的方法是一样的,今天我选择的是选取最后一位元素作为基准值。
1、hoare法
代码实现:
//hoare法
int partition(int array[], int left, int right)
{
int begin = left;
int end = right;
int pivot = array[right];
while (begin < end)
{
while (begin < end && array[begin] <= pivot)
{
begin++;
}
while (begin < end && array[end] >= pivot)
{
end--;
}
int t1 = array[begin];
array[begin] = array[end];
array[end] = t1;
}
int t2 = array[begin];
array[begin] = array[right];
array[right] = t2;
return begin;
}
- 挖坑法
代码实现:
//挖坑法
int partition(int array[], int left, int right)
{
int begin = left;
int end = right;
int pivot = array[right];
while (begin < end)
{
while (begin < end && array[begin] <= pivot)
{
begin++;
}
array[end] = array[begin];
while (begin < end && array[end] >= pivot)
{
end--;
}
array[begin] = array[end];
}
array[begin] = pivot;
return begin;
}
3.前后指针法
代码实现:
//前后指针法
int partition(int array[], int left, int right) {
//[left, div) 比基准小
//[div, i) 比基准值大于等于
int div = left;
int i = left;
for (; i < right; i++)
{
if (array[i] < array[right])
{
int t = array[i];
array[i] = array[div];
array[div] = t;
div++;
}
}
int temp = array[div];
array[div] = array[right];
array[right] = temp;
return div;
}
2.快速排序之非递归算法
利用栈来实现,我写的是c++版的
基本步骤:对原数组进行一次划分,分别将左边的left和右边的right入栈 stack。
判断stack是否为空,若是,直接结束;若不是,输入high、low来记录,两个元素并出栈
如果high大于low继续压栈,否则进行分组处理
循环步骤 2、3。
代码实现:
#include <stack>
void quickSortIn(int array[], int left, int right)
{
std::stack<int> s;
s.push(left);
s.push(right);
while (!s.empty())
{
int high = s.top(); s.pop();
int low = s.top(); s.pop();
if (low >= high)
{
continue;
}
int pivotIndex = partition(array, low, high);
s.push(pivotIndex + 1);
s.push(high);
s.push(low);
s.push(pivotIndex - 1);
}
}
void quickSort(int array[], int size)
{
quickSortIn(array, 0, size - 1);
}