快速排序

1.概念

快速排序算法是对冒泡排序算法的一种改进算法,在当前所有内部排序算法中,快速排序算法被认为是最好的排序算法之一。

2.基本思想

快速排序的基本思想: 通过一趟排序将待排序的序列分割为左右两个子序列,左边的子序列中所有数据都比右边子序列中的数据小,然后对左右两个子序列继续进行排序,直到整个序列有序。

例如我们对以下的数字进行排序:
5 4 2 3 1 6
我们首先先选择一个中间数字:例如可以选择 2(2 是这串数字的物理上 的中间数字,当然也可以选择其他的数字,另外我们只是选择了这个数字的值作为中间数,并不是将它取出来)
然后把小于 2 的数字放到左边,大于 2 的数字放到右边。等于 2 的数字放到那边都可以。

我们只需要找到 最左边大于等于 2 的数,找到最右边小于等于 2 的数,然后交换它们的位置即可。(两者都可以选择等于 2 的数,是因为这样可以更好的判断结束的条件,即最左边大于等于 2 的数和最右边小于等于 2 的数重合的时候)


5 4 2 3 1 6 进行排序,中间数字选 2
5 4 2 3 1 6 最左边大于等于 2 的数是 5,最右边小于等于 2 的数是 1,交换两者
1 4 2 3 5 6 最左边大于等于 2 的数是 4,最右边小于等于 2 的数是 2,交换两者
1 2 4 3 5 6 最左边大于等于 2 的数是 2,最右边小于等于 2 的数字是 2,两者重合,结束

1 2 4 3 5 6 分析我们可以发现,这行数字被分为了两个部分,a: 1 2b: 4 3 5 6,我们可以看到左边的数字都比右边的数字小,现在我们只要对这两个部分分别进行排序,那么这行数字就排序成功了。这就是分治的思想。


a: 1 2 进行排序。中间数字选 1
1 2 结束,分为两个部分 aa: 1 ab: 2

b: 4 3 5 6 进行排序。中间数字选 3
4 3 5 6 最左边大于等于 3 的数是 4,最右边小于等于 3 的数是 3,交换两者
3 4 5 6 最左边大于等于 3 的数和最右边小于等于 3 的数字都是 3,两者重合,结束,分为两个部分 ba: 3 bb: 4 5 6

aa: 1 ab: 2 ba: 3 bb: 4 5 6
aa、ab 和 ba 都只有一个数字了,不需要再次进行排序


bb: 4 5 6 进行排序。中间数字选 5
4 5 6 最左边大于等于 5 的数和最右边小于等于 5 的数字都是 5,两者重合,结束,分为两个部分 bba: 4 5 bbb: 6

aa: 1 ab: 2 ba: 3 bba: 4 5 bbb: 6
bbb 只有一个数字了,不需要再次进行排序


bba: 4 5 进行排序。中间数字选 4
4 5 最左边大于等于 4 的数和最右边小于等于 4 的数字是 4,两者重合,结束,分为两个部分 bbaa: 4 bbab: 5

aa: 1 ab: 2 ba: 3 bbaa: 4 bbab: 5 bbb: 6
全部排序成功,最后结果是:1 2 3 4 5 6,排序成功。

3.代码实现

#include <iostream>  
#include <algorithm>
using namespace std; 
const int N = 100010;
int q[N];  
  
void quick_sort(int* arr, int l, int r) {  
    if (l >= r) return; //递归结束条件,即只有一个数字了  
  
    int i = l - 1, j = r + 1, x = arr[(l + r) >> 1]; //-1和+1是为了确保do...while循环顺利进行,x取中间值最好  
    while (i < j) {  
        do i ++ ; while (arr[i] < x); //找到左边第一个大于等于x的值(从左往右)  
        do j -- ; while (arr[j] > x); //找到右边第一个小于等于x的值(从右往左),以上为确定排序顺序的条件  
        if (i < j) swap(arr[i], arr[j]); //交换两者  
    }  
  
    quick_sort(arr, l, j); //把左边的排序  
    quick_sort(arr, j + 1, r); //把右边的排序  
}  
  
//需要注意的是,每次递归都可以确定两个部分的顺序之分,可以根据这个特点,来求解第k大的数等问题  
  
int main() {  
    int n;  
    cin >> n;  
    for (int i = 0; i < n; i ++ ) {  
        cin >> q[i];  
    }  
    quick_sort(q, 0, n - 1); //传入,下标为要排序的下标  
    for (int i = 0; i < n; i ++ ) {  
        printf("%d ", q[i]);  
    }  
    return 0;  
}
posted @ 2024-03-01 21:37  ora12321  阅读(16)  评论(0编辑  收藏  举报