2
void qsort(vector<int>& vec, int low, int high) {
    if (low > high) return;
    int slow = low, pivot = vec[low];
    // 要对**除了主元的所有元素**进行划分,因此循环的边界很好理解
    for (int fast = low+1; fast <= high; ++fast)
        if (vec[fast] <= pivot) {   // <= 或 < 都是对的~
            slow++;
            swap(vec[slow], vec[fast]);
        }
    swap(vec[low], vec[slow]);    // 划分完成后再将主元放到其最终位置
    qsort(vec, low, slow-1);    // vec[slow](即主元)不需要参与排序,
    qsort(vec, slow+1, high);   // 因为它已经处于正确位置
}

思路就是,每次划分(将数组小于等于pivot和大于pivot的元素分开)的时候,用一个慢指针和一个快指针。每当快指针扫描到小于等于pivot的元素,就将这个元素丢到慢指针的位置(同时慢指针增加)。慢指针指向的元素以及其左边的元素,全都是被快指针丢过来的(也就是小于等于pivot的)。

之所以叫“慢”指针,是因为这个指针只有在快指针发现【小于等于pivot的元素】的时候才会增加,走得比快指针慢。

可以想象到,快指针扫描过程中的任何时刻,慢指针指向、以及其左边的元素都是小于等于pivot的,慢指针与快指针之间的元素都是大于pivot的。

思路来自 https://www.geeksforgeeks.org...

geeksforgeeks可以测试其正确性。提交代码:

#include <iostream>
#include <vector>
using namespace std;

void swap(int& a, int& b) {
    int t = a;
    a = b;
    b = t;
}

void qsort(vector<int>& vec, int low, int high) {
    if (low > high) return;
    int slow = low, pivot = vec[low];
    for (int fast = low+1; fast <= high; ++fast)
        if (vec[fast] <= pivot) {
            slow++;
            swap(vec[slow], vec[fast]);
        }
    swap(vec[low], vec[slow]);
    qsort(vec, low, slow-1);
    qsort(vec, slow+1, high);
}


void test() {
    int size;
    cin >> size;
    vector<int> vec(size);
    for (int i = 0; i < size; ++i) {
        cin >> vec[i];
    }
    qsort(vec, 0, size-1);
    for (int i = 0; i < size; ++i) {
        cout << vec[i] << ' ';
    }
    cout << endl;
    return;
}

int main() {
    int testNum;
     cin >> testNum;
     while (testNum--) {
         test();
     }
    return 0;
}

其实这个算法不一定要选择第一个元素作为主元。如果你想选择第i个元素作为pivot,先将第i个元素与第一个元素交换一下,后面不就和刚才的算法一样了吗~


最坏情况:和其他快排一样,每次选择pivot的时候都恰好选到了最大或最小的那个,对size为n的数组进行划分,得到的却是n-1的数组,因此要进行n次划分。因此这种情况下,时间复杂度为n+(n-1)+(n-2)+....+0,也就是O(n^2)。


csRyan
1.1k 声望198 粉丝

So you're passionate? How passionate? What actions does your passion lead you to do? If the heart doesn't find a perfect rhyme with the head, then your passion means nothing.