快速排序
基本思想:通过一趟排序将要排序的数据分割成独立的两部分,分割点左边都是比它小的数,右边都是比它大的数。
然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。

详细的图解往往比大堆的文字更有说明力,所以直接上图:

上图中,演示了快速排序的处理过程:
初始状态为一组无序的数组:2、4、5、1、3。
经过以上操作步骤后,完成了第一次的排序,得到新的数组:1、2、5、4、3。
新的数组中,以2为分割点,左边都是比2小的数,右边都是比2大的数。
因为2已经在数组中找到了合适的位置,所以不用再动。
2左边的数组只有一个元素1,所以显然不用再排序,位置也被确定。(注:这种情况时,left指针和right指针显然是重合的。因此在代码中,我们可以通过设置判定条件left必须小于right,如果不满足,则不用排序了)。
而对于2右边的数组5、4、3,设置left指向5,right指向3,开始继续重复图中的一、二、三、四步骤,对新的数组进行排序。
复杂度和稳定性情况:
- 最好的时间复杂度:O(nlog n)
- 最坏的时间复杂度:O(n²)
- 平均的时间复杂度:O(nlog n)
- 空间复杂度:O(log n)
- 稳定性:不稳定
C++实现快排(递归版)
// 快速排序
void QuickSort(vector<int> &a, int left, int right)
{
// 递归边界条件
if (left >= right)
return;
if (left < 0 || right >= a.size())
return;
// 以最左边的数(left)为基准
int base = a[left];
int i = left, j = right, tmp;
while (i < j) {
// 从序列右端开始,向左遍历,直到找到小于base的数
while (a[j] >= base && i < j)
j--;
// 从序列左端开始,向右遍历,直到找到大于base的数
while (a[i] <= base && i < j)
i++;
if (i < j)
{
int tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}
}
// 基准数归位
a[left] = a[i];
a[i] = base;
// 对“基准标号“左侧的一组数值进行递归的切割,以至于将这些数值完整的排序
QuickSort(a, left, i - 1);
// 对“基准标号“右侧的一组数值进行递归的切割,以至于将这些数值完整的排序
QuickSort(a, i + 1, right);
}
int main()
{
int arr[] = { 6, 4, 8, 9, 2, 3, 1 };
vector<int> test(arr, arr + sizeof(arr) / sizeof(arr[0]));
cout << "排序前" << endl;
for (int i = 0; i < test.size(); i++){
cout << test[i] << " ";
}
cout << endl;
vector<int> result = test;
QuickSort(result, 0, result.size() - 1);
cout << "排序后" << endl;
for (int i = 0; i < result.size(); i++){
cout << result[i] << " ";
}
cout << endl;
return 0;
}
C++实现快排(非递归版)
借助一个栈,边划分边排序
int Divide(vector<int> &a, int left, int right)
{
int base = a[left];
while(left < right)
{
while(left < right && a[right] >= base)
right--;
a[left] = a[right];
while(left < right && a[left] <= base)
left++;
a[right] = a[left];
}
a[left] = base;
return left;
}
void QuickSort(vector<int> &a, int left, int right)
{
stack<int> s;
if(left < right)
{
int base = Divide(a, left, right);
if(left < base-1)
{
s.push(left);
s.push(base-1);
}
if(base+1 < right)
{
s.push(base+1);
s.push(right);
}
while(!s.empty())
{
int r = s.top();
s.pop();
int l = s.top();
s.pop();
int b = Divide(a, l, r);
if(l < b-1)
{
s.push(l);
s.push(b-1);
}
if(r > b+1)
{
s.push(b+1);
s.push(r);
}
}
}
}
int main()
{
int a[] = {5,6,3,2,8,9,0};
int len = sizeof(a)/sizeof(a[0]);
vector<int> v(a,a+len);
QuickSort(v, 0, v.size()-1);
for(int i = 0; i < v.size(); ++i)
{
cout<<v[i]<<" ";
}
cout<<endl;
return 0;
}
其他排序算法:
本文详细介绍了快速排序的基本思想、实现步骤及复杂度分析,并提供了C和C++两种语言的递归与非递归版本的实现代码。
658






