快速排序C语言实现

在学完冒泡排序和选择排序这两个入门级别的排序方法后,打算挑战一下自己,尝试一下快速排序。第一次只是看了别人的博客和视频,没有动手在草稿本上验算,所以学的云里雾里。这次自己一步一步分析,并拿笔大量验算,总算大概理解了快速排序的本质及其中的重难点。

快排的本质

快排体现的是分治和递归的思想。

用简明直白的话描述步骤就是:

1、每次选取一个基准数(一般为数列最左或最右的数),通过移动代表下标的变量不断把小于基准数的数移到左部分,将大于基准数的数移到又部分,最后将基准数置于两部分之间。

2、这时左部分都小于基准数,右部分都大于基准数,但左、右部分内可能是乱序的,所以不断地将每部分看做一个新数列,对其使用快排,直到整个数列排序好。

 具体实现步骤

1、在所有数字中选择一个数字作为排序的基准(pivot),在操作数列中选择最左边的数字标记为左标记 ,最右边的数字标记为右标记

2、将右边的标记向左移动,当右标记达到小于 pivot 的数字时,停止移动
3、然后将左边的标记向右移动,当左标记达到大于 pivot 的数字时,停止移动
当左右标记停止时,交换左右标记的数字


因此,左标记 的作用是找到一个大于 pivot 的数字,右标记 的作用是找到一个小于 pivot 的数字通过交换数字,可以在数列的左边收集小于 pivot 的数字集合,右边收集大于 pivot 的数字集合交换1、之后,持续步骤2、3

4、当 右标记 碰撞到 左标记 时也停止移动
如果左右侧的标记停止时,并且都在同一个位置,将这个数字和 pivot 的数字交换
这就完成了第一次操作

5、然后递归对这分成的两部分都执行同样的操作,完成快速排序

代码实现及难点分析

#include <stdio.h>
void quick_sort(int num[], int low, int high)
{
    int i, j, temp;
    int tmp;

    i = low;
    j = high;
    tmp = num[low];   //任命为中间分界线,左边比他小,右边比他大,通常第一个元素是基准数
                      
    if (i > j)  //如果下标i大于下标j,函数结束运行(递归的结束条件)
        //如何理解递归结束条件:任意序列(无论是乱序还是正序)使用快排的最终结果都是只剩一个数,此时j,i重合
        //如果以最左值为基准再次排序,那么此时i为此数下标,j为i-1,i>j,结束递归
    {
        return;
    }

    while (i != j)
    {
        while (num[j] >= tmp && j > i)//j>i可以保证j和i最后一定能重合
        {
            j--;
        }//注意:先让j--最终j,i重合结果是比基准值小的数;
        //       先让i--最终j,i重合结果是比基准值大的数

        while (num[i] <= tmp && j > i)
        {
            i++;
        }

        if (j > i)//没有重合就交换值
        {
            temp = num[j];
            num[j] = num[i];
            num[i] = temp;
        }
    }

    num[low] = num[i];//直到重合后交换基准数和重合时的数(将基准数放到j,i重合位置)
    num[i] = tmp;

    quick_sort(num, low, i - 1);//对基准数左右两边分别进行快排
    quick_sort(num, i + 1, high);
}

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

    quick_sort(num, 0, 10 - 1);

    for (i = 0; i < 10; i++)
    {
        printf("%d ", num[i]);
    }

    return 0;
}

以上代码通过注释已经较为详细的讲解了快排的基本步骤,下面来重点讲解一些注意事项:

1、一般选取最左值或最右值为基准数,如果选取最左值,则先移动代表右边数下标的变量 j ,如果选取最右值,则先移动代表左边数下标的变量 i 。

2、对递归结束条件的理解:如何理解递归结束条件:任意序列(无论是乱序还是正序)不断使用快排的最终结果都是只剩一个数,此时 j , i 重合。 如果以最左值为基准再次排序,那么此时i为此数下标,j为 i-1, i > j,于是结束递归。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值