关于快速排序算法的学习心得

快速排序的时间复杂度为O(nlogn)。

关于快速排序的几点注意事项:

  1. 每次排序先选取一个元素,记为flag。目的是排序后保证flag左边的数不大于flag,右边的数不小于flag。一般以第一个元素为准。该位置元素默认“取出”。
  2. 最左边的元素下标记为low,指向最左边元素。最右边的元素下表记为high。
  3. 先看high元素是否大于flag,若大于等于则继续左移high。若小于则将high对应元素放到low上(此时low对应flag,已取出)并右移low(这里判定条件为如果low指向元素大于flag或者high指向元素小于flag,需要赋值元素,则切换移动的指针并移动(被赋值的位置不用比较,肯定符合要求),否则继续移动当前指针),直到low high位置重合为止,此时将flag赋值到该位置即可。

具体步骤:

以 18 53 8 12 1 47 6 23为例,以18为flag,具体步骤如下(蓝色代表low,红色代表high)

  1. 先看high,因为23 大于18,high继续左移

2.此时high->6,因为6<18,所以将6赋给low对应的值,并移动low(因为赋值过后low的值变成6,6一定小于18,所以直接移动low即可,后面以此类推)

3.此时low->53,因为53>18,所以将53赋值给high对应的值并移动high

4.此时high->47,因为47>18,所以继续左移high

5.此时high->1,因为1<18,所以将1赋给low对应的值,并右移low

6.此时low->8,因为8<18,继续右移low

7.此时low->12,因为12<18,继续右移low

8.此时low high重合,将flag值放到该下标即可。

这样,找到了第一个中间元素,左边的元素一定不大于flag,右边的元素一定不小于flag。

以此类推,处理flag左边的部分和flag右边的部分即可,直到长度为1停止。

代码如下(flag代表每次选出的中间数,左边不大于flag,右边不小于flag):

int sort(int *s,int low,int high)

{

    int flag=s[low];

    while(low<high)//high low重合停止

    {

        while(low<high&&flag<=s[high])

        {

            high--;//flag不大于high指向元素,high继续左移

        }

        if(low<high)

        {//遇到需要放到左边元素,将high指向元素直接赋值到low位置

            s[low]=s[high];

        }

//有交换操作后开始移动L

        while(low<high&&flag>=s[low])

        {

            low++;//flag不小于low指向元素,low继续右移

        }

        if(low<high)

        {

//遇到需要放到右边元素,将low指向元素直接赋值到high位置

            s[high]=s[low];

        }

//交换操作之后继续执行high左移操作直到high low重合

    }

    s[high]=flag;//将flag放到high low重合位置

    return high;

}

int quick_sort(int *s,int low,int high)

{

    int ret=0;

    if(low<high)//序列长度为1作为递归出口,此时low>=high

     {

         ret=sort(s,low,high);//函数返回了low high重合位置

         quick_sort(s,ret+1,high);

         quick_sort(s,low,ret-1);

     }

}                               

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值