物联网
您现在所在的位置:首页>企业动态>物联网

十大排序算法——快速排序

编辑:学到牛牛IT培训    发布日期: 2023-08-01 09:11:26  

在对于刚接触编程这个领域的同学,对排序还没有一定的了解的时候,就光是听到快速排序这个名称就会觉得很有吸引力,这个名字取得粗鲁且自信,让人不得不想去了解一下他自信的来源


1.png


快速排序其实是对冒泡排序的一种改进,名字里面的快速两个字得确也有自信的实力,它相对于其他几种排序来说效率较高,速度更快,但对于初学者而言,快速排序还是很难理解的,因为快速排序的一些特殊性,现在很多公司也会去选择它作为面试的考题,如果仅仅是依靠背代码,默写的方式的话估计很难去把快速排序写好,所以我们这个时候就得知道思路的一个重要性,只有把它的思想理解到位,我们才能更快的把快速排序学会。


首先,我们先来看一下快速排序的一个概念

快速排序是指通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行之前的操作,以此达到整个数据变成有序序列。


我们根据它的概念来详细看一下快速排序的思路

第一步如图1-1所示,先得去找一个基准数,一般来说数组第一个为基准数,现在可以理解为数组第一个数赋值给了key,成为基准数,数组的第一个位置产生了空缺(有位置没人坐)

int key = a[i];

再去找到一个最左边的下标,一个最右边的下标(其实就是长度减一)

int left = 0, int right = 6; 


1.gif

图1-1

(若出稿请在素材中更换此图,删除本句话)


因为左右两个下标是不会变动的,所以后期为了我们数组左右两边的数能够和基准数更好的进行比对,我们再去定义两个下标i,j分别等于left,right(如图1-2所示)

int i = left,j = right;

i 和 j就会一个从左边进行比较,一个从右边进行比较,记录每次比较之后的下标


3.gif

图1-2


接下来从右边第一个数开始和基准数对比,该数如果大于基准数的话(a[j] > key),它的位置则不变,继续下一个数的对比(j--),如果小于基准数的话(a[j] < key),就结束右边的对比,该数就放到空缺的位置上面去(a[i] = a[j]),新的空缺位产生 (如图1-3所示)

while( (a[j] > key))

{

j--;

}

a[i] = a[j];


4.gif

图1-3

(若出稿请在素材中更换此图,删除本句话)




接下来再从左边的数开始和基准数对比,如果该数比基准数小(a[i] < key),则位置保持不变,继续下一个数的对比(i++),如果比基准数大(a[i] > key)则结束左边的对比,该数移到空缺位(a[j] = a[i]),新的空缺位产生(如图1-4所示)

while( (a[i] < key))

{

i++;

}

a[j] = a[i];



图1-4

(若出稿请在素材中更换此图,删除本句话)



继续从右边上一次的位置进行之前相同的操作(如图1-5所示)

5.gif

图1-5

(若出稿请在素材中更换此图,删除本句话)



现在就回到了左边,我们可以清晰的看到i 和 j已经相遇了那这个时候第一次对比结束,将基准数放回最后的空缺位置,a[i] = key;

第一次快排结束(如图1-6所示)

这时候聪明的同学就会发现一个隐藏条件,也是循环的退出条件 i < j 


6.gif

图1-6

(若出稿请在素材中更换此图,删除本句话)


第一次快排结束之后整个排序并没有结束,接下来我们通过递归继续剩下来的对比,由之前这个基准数为界,划分为左右两部分,两部分同时进行第一次快排相同的步骤,直到全部比较完变成一个有序的数组

sort(a,left,i-1);

sort(a,i+1,right);



以上呢,是数组实现快速排序的基本步骤,一些重点的代码部分也写了出来,为的就是让同学们学会将思想转化为代码


那接下来我们来一起看看快速排序的完整代码


#include <stdio.h>



void sort(int a[],int left,int right)

{

int i = left,j = right;

int key = a[i];

if(left >= right) //左边始终要小于我们的右边,如果等于结束整个程序

return;

while(i < j)  //  每次快排退出条件

{

while((i < j) && (a[j] > key))

{

j--;

}

a[i] = a[j];

    while((i < j) && (a[i] < key)) // 这里的i < j防止上面的j减过头导致程序出现错误

{

i++;

}

a[j] = a[i];

}

a[i] = key;

sort(a,left,i-1);     //递归将数组分成两部分同时进行快排

sort(a,i+1,right);   //  i  就是第一次快排相遇的下标位置

}


int main()

{

int i;

int a[]={2,1,5,4,6,3};

int len = sizeof(a)/sizeof(a[0]);

sort(a,0,len-1);      //传参,left = 0,right = 长度 - 1

for(i = 0; i < len; i++)

{

printf("%d",a[i]);

}

printf(" ");

return 0;

}



免费试学
课程好不好,不如实地听一听

封闭学习

2

1

联系我们

电话:028-61775817

邮箱:1572396657@qq.com

地址:成都市金牛区西城国际A座8楼

  • 物联网_物联网专题新闻_物联网IOT资讯-学到牛牛
    物联网_物联网专题新闻_物联网IOT资讯-学到牛牛

    扫一扫,免费咨询

  • 物联网_物联网专题新闻_物联网IOT资讯-学到牛牛
    物联网_物联网专题新闻_物联网IOT资讯-学到牛牛

    微信公众号

  • 物联网_物联网专题新闻_物联网IOT资讯-学到牛牛
物联网_物联网专题新闻_物联网IOT资讯-学到牛牛

学一流技术,找高薪工作

物联网_物联网专题新闻_物联网IOT资讯-学到牛牛

7-24小时服务热线:

028-61775817

版权声明 网站地图

蜀ICP备2021001672号

课程问题轻松问