Skip to content
本页目录

5快速排序-最优

发布时间:

思想

  • 通过一趟排序将待排记录分割成独立的两部分,其中一部分记录的关键字均比另一部分记录的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序。

  • 假设待排序的序列为{a[L],a[L+1],a[L+2],……,a[R]},首先选取第一个记作为pivot或支点),定义两个指针i和j分别指向第二个和最后一个位置 ,则首先从j所指位置起向前搜索找到第一个关键字小于pivot的记录,然后从i所指位置起向后搜索,找到第一个关键字大于pivot的记录,将它们互相交换,重复这两步直至i>=j为止,最后将pivot值与j处的值交换,完成一趟快速排序。

  • 将pivot左右两边部分重复调用以上方法达到整个排序完成。

  • 快速排序的时间的复杂性是O(nlog2n),速度快,但它是不稳定的排序方法。就平均时间而言,快速排序是目前被认为是最好的一种内部排序方法

  • 由以上讨论可知,从时间上看,快速排序的平均性能优于前面讨论过的各种排序方法,但快速排序需一个栈空间来实现递归。若每一趟排序都将记录序列均匀地分割成长度相接近的两个子序列,则栈的最大深度为log(n+1)。

js
#include <iostream>
using namespace std;

int a[] = {3, 1, 7, 4, 9, 6, 2, 5, 8};
int len = sizeof(a) / sizeof(a[0]);

void showA() {
    for (int i = 0; i < len; i++) {
        cout << a[i] << " ";
    }
    cout << endl;
}

void qsort(int l, int r) {
    int i = l + 1;
    int j = r;
    int pivot = l;
    do {
        while (a[i] < a[pivot])
            i++;  // 在左半部分寻找比中间数大的数
        while (a[j] > a[pivot])
            j--;  // 在右半部分寻找比中间数小的数

        if (i < j) {  // 若找到一组与排序目标不一致的数对则交换它们
            swap(a[i], a[j]);
            showA();
            i++;
            j--;  // 继续找
        }
    } while (i < j);  // 注意这里不能有等号
    if (j != pivot) {
        swap(a[pivot], a[j]);
        showA();
    }

    if (j - 1 > l) {
        qsort(l, j - 1);  // 若未到两个数的边界,则递归搜索左右区间
    }

    if (i < r) {
        qsort(i, r);
    }
}

int main() {
    qsort(0, len);
    showA();
}

   

上次更新: