快速排序详解

1、快速排序思想:

(1)、确定分界点:

①、左边界 "q[l]"                ②、中间值 "q[l + r] / 2"                ③、右边界 "q[r]"。

(2)、调整范围(难点):

假设 "x" = "中间值",以 "x" 为分界点,通过调整数值,使得 "x" 左边的数都小于等于 "x";"x" 右边的数都大于等于 "x"。

(3)、递归排序处理:

用递归将 "x" 左边的数和右边的数都排好序,然后再将两者拼接到一起,就得到一个排好序的完整区间。

2、"快速排序思想" 中步骤2 "调整范围" 具体调整方法:

(1)、定义两个指针 "i" 和 "j" 分别指向左右边界,两个指针同时往中间走;

(2)、首先 "i" 往右边走,如果 "i" 所在位置的数小于 "x", 那么就继续往右边走,当 "i" >= "x" 时,"i" 就停止移动;

(3)、然后 "j" 就往左边走,如果 "j" > "x",那么就继续往左边移动,当 "j" <= "x" 时, "j" 就停止移动;

(4)、这时 "i" 和 "j" 所在位置的数都错位了,需要将两者交换一下位置,因为 "x" 左边的数都小于等于 "x";"x" 右边的数都大于等于 "x"。"i" 和 "j" 交换了位置之后,继续执行上述操作。

(5)、直到 "i" 和 "j" 相遇为止。这样就能将整个区间一分为二,左边的数都小于等于 "x";右边的数都大于等于 "x"。

3、快速排序中的递归详细解释:

首先快速排序先确定分界点,再划分区间,使得 "x" 左边的数都小于等于 "x";"x" 右边的数都大于等于 "x"。把上述做好后,再进行最后的递归排序。

假设:数组 = "{1, 2, 3, 4, 5}"。此时数组已经完成了前两个步骤,还差最后的递归排序。

(1)、先看左区间 "{1, 2, 3}",把左区间 "{1, 2, 3}" 看作一个整体,对左区间进行步骤一二的操作过程。

(2)、然后区间 "{1, 2, 3}" 拆分为左区间 "{1, 2}" 和右区间 "{3}" 进行递归。

(3)、然后看左区间 "{1, 2}",把左区间 "{1, 2}" 看作一个整体,对左区间进行步骤一二的操作过程。这时 "{1, 2}" 就排好序了。

(4)、然后区间 "{1, 2}" 拆分为左区间 "{1}" 和右区间 "{2}" 进行递归。

(5)、区间 "{1}" 递归时,遇到递归结束条件直接 "return" 返回停止递归。

(6)、然后递归区间 "{2}",也是遇到递归结束条件直接 "return" 返回停止递归。

(7)、区间 "{1, 2}" 已经排好序了,这时对区间 "{3}" 进行递归,也是遇到递归结束条件直接 "return"。

(8)、这时左区间 "{1, 2, 3}" 已经排好序了,然后来到右区间 "{4, 5}"。

(9)、对右区间 "{4, 5}" 进行步骤一二的操作过程,这时 "{4, 5}" 就排好序了。

(10)、然后递归区间 "{4}",也是遇到递归结束条件直接 "return" 返回停止递归。

(11)、然后递归区间 "{5}",也是遇到递归结束条件直接 "return" 返回停止递归。

(12)、这时左区间 "{4, 5}" 已经排好序了。

(13)、最后左右区间都排好序了,合并到一起就是完整的排序区间。  

4、代码实现:

#include <iostream>
#include <algorithm>

using namespace std;

const int N = 1e6 + 10;

int n;
int q[N];

void quick_sort(int q[], int l, int r)
{
    if (l >= r)  //也可以写成"l == r"
    {
        return;
    }

    //因为要从左右边界点开始判断,所以左边界最开始的起点要在左边界的前一位,右边界最开始的起点要在右边界的后一位。
    int x = q[l + r >> 1], i = l - 1, j = 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);
}

int main()
{
    scanf("%d", &n);
    for (int i = 0; i < n; i++)
    {
        scanf("%d", &q[i]);
    }

    quick_sort(q, 0, n - 1);

    for (int i = 0; i < n; i++)
    {
        printf("%d ", q[i]);
    }

    system("pause");
    return 0;
}

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值