首页 > 编程语言 > 详细

快速排序算法

时间:2021-08-12 23:33:55      阅读:19      评论:0      收藏:0      [点我收藏+]

技术分享图片

题目链接:https://www.acwing.com/problem/content/description/787/

吐槽:看了好几种快速排序的代码,要么是pivot为左边界AC不通过,要么就是边界情况没考虑清楚。属实恶心
下面写了3种AC通过的代码。

先介绍下基本知识
快速排序的基本思想是基于分治策略的,其算法思想如下。

  1. 分解:先从数列中取出一个元素作为基准元素(左、中、右、随机)。以基准元素为标准,将问题分解为两个子序列,使小于或等于基准元素的子序列在左侧,使大于基准元素的子序列在右侧。
  2. 治理:对两个子序列进行快速排序
  3. 合并:将排好序的两个子序列合并在一起,得到原问题的解。

第一种方法:

算法步骤:

  1. 首先选取数组的第一个元素作为基准元素pivot = q[l], i = l, j = r
  2. 先从右往左扫描,找小于pivot的数,如果找到,则q[i]和q[j]交换,且i++
  3. 从左向右扫描,找大于pivot的数,如果找到,则q[i]和q[j]交换,且j--
  4. 重复步骤2~3,直到i和j重合,所指的位置正好是pivot元素
  5. 至此一趟排序完成。此时以pivot为界,将数据分为两个子序列,左侧子序列元素都比pivot小,右侧子序列元素都比pivot大,然后再分别对这两个子序列进行快速排序。

注意:详细细节写在代码中

C++代码
void quick_sort(int q[], int l, int r){
    if (l >= r) return; //递归出口:当区间没有元素 或 只有一个元素时 结束
    int x = l + r >> 1, i = l, j = r; //直接选取左边界会超时,那么就选取中间元素,然后和左边界元素交换
    swap(q[l], q[x]); //中间元素 和 左边界交换 
    int pivot = q[l]; //相当于pivot选取的是中间元素  步骤1完成
    while(i < j){
        while(i < j && q[j] > pivot) j--; // 写<=会超时 同下 并且一定先从j开始
        if(i < j) swap(q[i++], q[j]);  //步骤2完成
        while(i < j && q[i] < pivot) i++;
        if(i < j) swap(q[i], q[j--]); //步骤3完成
    }
    // i == j时退出循环 此时i和j所指的元素正好是pivot 递归处理左右
    quick_sort(q, l, i - 1);
    quick_sort(q, i + 1, r);
}

第二种方法:y总总结的模板

代码是用do-while实现了,感觉不太好了解

C++代码
void quick_sort(int q[], int l, int r)
{
    if (l >= r) return;
    int i = l - 1, j = r + 1, x = q[l + r >> 1];
    while (i < j)
    {
        do i ++ ; while (q[i] < x);
        do j -- ; while (q[j] > x);
        if (i < j) swap(q[i], q[j]);
    }
    quick_sort(q, l, j);
    quick_sort(q, j + 1, r);
}

第三种方法:类似y总总结的模板

代码是用while实现了,应该理解好多

void quick_sort(int q[], int l, int r){
    if(l >= r) return;
    int i = l, j = r, x = q[l + r >> 1];
    while(i <= j){ // <=的目的:将i=j的情况继续处理,直至i>j,下面的i<=j同理 
        while(q[i] < x) i++; //  <的目的:若用<=,则会在数据为大量重复数字时发生数组下标越界 
        while(q[j] > x) j--; // 此时 i 和 j 都指向不符合条件的元素
        if(i <= j) swap(q[i++], q[j--]); //将 i 和 j 交换 然后 两个指针分别移动一位
    }
    //此时 j < i,即j在i的左边一位
    quick_sort(q, l, j); 
    quick_sort(q, i, r);
}

快速排序算法

原文:https://www.cnblogs.com/keyongkang/p/15134907.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!