首页 > 编程知识 正文

c语言快速排序和冒泡排序(快速排序均快于冒泡排序)

时间:2023-05-04 10:39:45 阅读:88266 作者:3653

前言

无论是今后的面试还是笔试,排名都在数据结构和算法中占有重要的地位,所以我决定好好写数据结构这个主题,进一步研究。 今天和大家一起学习交换类排行榜——冒泡和快速排行榜的详细信息!

排行榜上最考察的是冒泡和快速排序,当然执行上的冒泡要比快速排序简单得多。 理解可以说是最简单的排序算法,早排很多面试笔试都要求手撕,所以重要性不言而喻! 当然,关于排序算法,我一开始接触学习的时候,只是萌萌哒地了解了一下,大概知道,背模板,快排队手写,刷题。 后来我意识到我是个笨蛋。java中有Arrays.sort ) )这个api,为什么我可以直接调用愚蠢的手写? 明明重新排列多个条件重新改写comparator界面就OK了,为什么还要愚蠢的手写? 从此,走上了没有手写的早排的不归路。

后来,渐渐地,这个序列思想很少被使用,被我的成功所遗忘。 现在,请重新被我捡起来,深入了解,不要让那位大人物有一天再牵着我的手丢脸。 把学习过程分享给大家。

冒泡排序

介绍

冒泡排序也称为起泡排序。 他是基于交换的序列的典型,也是早排思想的基础。 关于泡沫排序名字的由来,百度百科是这样说的:

这个算法名字的由来是,元素越小,通过交换就会慢慢地“漂浮”在数列的最上面。 为了让碳酸饮料中的二氧化碳气泡最终浮在最上面,名字是“冒泡排序”。

当然,泡沫排序是一种稳定的排序算法,时间复杂度为o(n^2^ )。 基本的想法是从前到后调整大要素(或从后到前调整小要素)。

分析

具体思想是(后面调整大要素) :

从第一个元素往后跑,判断每个位置是否比后面的元素大。 如果大于后面的元素,则更换两个大小,然后向后移动。 如果不是,就这样往后走。 这样的话,进行一个回合后,保证最大的数量被更换到最后的位置。 那么,第二次也同样从开始向后判断前进,如果现在位置比后面的位置大,就换他后面的数量。 但是,请注意一点。 这次不需要判断到最后。 判断到倒数第二个位置就行了。 (因为首先确定了最大的是倒数第一个,所以这次的目的是确定倒数第二个。 )同样地,在第一个要素将整个要素有序化之前,之后的操作也是如此。 举个例子,例如用2、8、9、3、7、6、12、4这种排列的泡沫排序来说。 有多次(7)重新排列,每次必须执行多次(8-k )。 最初的排序如下所示。

多次排序的结果如下所示。

动态执行的顺序如下。

代码

具体实现的时候,要弄清楚是从小到大,还是从小到大,另外也要注意次数,注意越界。 气泡排序的键码如下所示。

私人建筑委员会(int [ ] a ) {

//todo auto -生成方法

for (英寸=长度- 1; i=0; I---- )

{

for(intj=0; ji; j )日本

{

               if(a[j]>a[j+1])                 {                     int team=a[j];                     a[j]=a[j+1];                     a[j+1]=team;                 }             }         }     }

快速排序

介绍

快速排序是对冒泡排序的一种改进,采用递归分治的方法进行求解。而快排相比冒泡是一种不稳定排序,时间复杂度最坏是O(n^2^),平均时间复杂度为O(nlogn),最好情况的时间复杂度为O(nlogn)。

分析

对于快排来说,基本思想是这样的

快排需要将序列变成两个部分,就是序列左边全部小于一个数,序列右面全部大于一个数,然后利用递归的思想再将左序列当成一个完整的序列再进行排序,同样把序列的右侧也当成一个完整的序列进行排序。

其中这个数在这个序列中是可以随机取的,可以取最左边,可以取最右边,当然也可以取随机数。但是通常我们取最左边的那个数。当然,为了实现这个目标,实现方式可能不一样,但是我这里采取的是大众常规的方式和方法。!

这里的一个难题就是如何处理将比第一个数K小的全部放左面,把比K大的全部放右面!如果没有什么技巧,直接硬性往里面塞,你肯定要一个额外存储空间先把整个先存了。然后遍历比较然后放入目标区域。当然这样太浪费空间内存了。我们为了节省计算机资源,采取这样的方法:

先用一个空间标记这个最左侧的数K。然后先从右往左high--先找到一个比这个K小的数a[high],把这个a[high]放到a[low]位置(因为这个a[low]的初始K已经被额外空间记录过,不用担心)。这样右侧不符合要求小于K的已经调到最左侧了,我们再从左侧向右low++一直到a[low]>K.也就是找到第一个比K大的数,它在左侧不符合要求所以我们把它移动到右侧,而我们刚刚所说的a[high]已经被赋值移到左侧,所以我们把这个a[low]大于K的数值移动到右端a[high]处,这样又保证high右侧全部大于K,low左侧全部小于K。就又开始重复第一步啦一直到low>high为止(即所有左侧都小于K,右侧都大于K)。

对于一个序列的2,8,3,7,6,9,4,12来说,它的执行过程图解大致是这样的:1 . 首先2是最小的,采用递归分治时候左侧相当于为空,只需要把右侧再进行排序。

2 .对于右侧序列来说,先用K储存a[low]=8我们先从右侧找到第一个小与8的数字4。

3 .我们将它放到low位置替换,然后从low位置向右找到第一个大于k=8的再同样放到右侧。我们找到9,把9赋值给high位置。

4 .重复上面步骤直到high

5 .就这样重复下去,直到整个序列有序即可!

代码

在书写代码的时候,要注意一些顺序,防止数组越界情况,可以写好debug一遍其实就很好理解了!当写代码遇到错误时候,不要急着就去找正确答案,能有时间自己发现错误,可以借助断点查看程序执行流程,这样对自己的收益是最大的!至于快排的代码,是这样的:

private static void quicksort(int [] a,int left,int right)     {         int low=left;         int high=right;         //下面两句的顺序一定不能混,否则会产生数组越界!!!very important!!!         if(low>high)//作为判断是否截止条件             return;         int k=a[low];//额外空间k,取最左侧的一个作为衡量,最后要求左侧都比它小,右侧都比它大。         while(low<high)//这一轮要求把左侧小于a[low],右侧大于a[low]。         {             while(low<high&&a[high]>=k)//右侧找到第一个小于k的停止             {                 high--;             }             //这样就找到第一个比它小的了             a[low]=a[high];//放到low位置             while(low<high&&a[low]<=k)//在low往右找到第一个大于k的,放到右侧a[high]位置             {                 low++;             }             a[high]=a[low];                  }         a[low]=k;//赋值然后左右递归分治求之         quicksort(a, left, low-1);         quicksort(a, low+1, right);          }

测试与总结

对于完整的代码,为

package 八大排序; import java.util.Arrays; public class 交换类排序 {     public static void main(String[] args) {         int a[]= {2,8,9,3,7,6,12,4};         xydcc(a);         System.out.println(Arrays.toString(a));         int b[]= {2,8,9,3,7,6,12,4};         quicksort(b, 0, b.length-1);         System.out.println(Arrays.toString(b));     }     private static void  xydcc(int[] a) {         // TODO Auto-generated method stub         for(int i=a.length-1;i>=0;i--)         {             for(int j=0;j<i;j++)             {                 if(a[j]>a[j+1])                 {                     int team=a[j];                     a[j]=a[j+1];                     a[j+1]=team;                 }             }         }     }     private static void quicksort(int [] a,int left,int right)     {         int low=left;         int high=right;         //下面两句的顺序一定不能混,否则会产生数组越界!!!very important!!!         if(low>high)             return;         int k=a[low];//取最左侧的一个作为衡量,最后要求左侧都比它小,右侧都比它大。         while(low<high)         {             while(low<high&&a[high]>=k)             {                 high--;             }             //这样就找到第一个比它小的了             a[low]=a[high];             while(low<high&&a[low]<=k)             {                 low++;             }             a[high]=a[low];                  }         a[low]=k;         quicksort(a, left, low-1);         quicksort(a, low+1, right);          } }

运行结果:

好了这个交换类排序就总结到这里了。总之,冒泡是很基础和容易,但是要注意这种简单排序所属的范畴(交换类)要和插入类等做好区分;而快排板子很好记,深入理解需要点时间消化吧。一次不行再来第二次,不行再来第三次,。。。

当然,如果感觉不错或者对你有所帮助,欢迎点赞收藏转发哈!如果感觉有问题或者纰漏还请指正哈!当然,笔者长期致力于<<数据结构与算法>>这个专栏的更新和维护,欢迎大家关注一波哈!

最后,欢迎关注笔者微信公众号(bigsai),头条号(一直码农一直爽)!

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。