java 快排_总结Java中的排序算法:选择排序&快排&堆排序&归并排序(后附视频讲解)...

选择排序

思路:遍历数组找到最小值,将它放在第一个位置(将第一个位置的数与最小值交换位置),再从第二个位置开始遍历,取出数组中第二小的数,放在第二个位置……重复上述过程完成排序。

代码:

public 

选择排序的实现比较简单,时间复杂度和冒泡一样是O(n^2)。接下来讲讲快排。

快排

思路:任意取一个数(一般取第一个),将数组内所有比它小的数放在它前面,比它大的数放在它后面,再对它的前后两部分重复上述操作,完成排序。

代码:

public 

总结:以{2,1,9,6,3,0}为例再说明一下快排的思路。

首先,令left=start,right=end(分别让它们处于头部和尾部),令mid=2,保存start位置的值。

先从尾部遍历:找到了0这个较小数,结束循环,把0放到left位置。此时数组变成了{0,1,9,6,3,0}。

再从头部遍历:如果当前数<mid,left++,直到找到9这个较大数,跳出循环,把9放到right位置(原来0的位置,现在0已经不需要这个位置了)。

现在9的原位置又空出来了,如果left<right,重复上述过程,把这个位置交给下一个较小数,再把较小数的原位置交给下一个较大数……

循环结束,最后找到的较大数的位置就空出来了,把这个位置赋给mid。

如此,便完成了比mid小的数放前面,比mid大的数放后面的移动过程。

接下来以[start和(left/right)-1],[(left/right)+1,end]作为新的区间重复上述过程即可。

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

堆排序

思路:将数组构建为一个大顶堆(所有节点都大于其左右子节点的完全二叉树),此时根节点即为数组中的最大值。删去根节点,将数组中最后一个元素移到根节点的位置(实际上是将根节点与最后一个元素交换位置),还剩下n-1个数,此时这些数构造成的完全二叉树不再是大顶堆,需要重新调整结构,使其成为大顶堆,根节点再次取到当前n-1个数中的最大值,再将其删去……重复上述操作,便可完成升序排列。

简单地说,就是每次都通过大顶堆的根节点取到当前序列的最大值,将它放到序列最后,再重复前面步骤,一步步实现升序排列。

同样的思路,可用小顶堆完成降序排列。

代码(升序排列):

public 

总结:做了一个视频来讲解堆排序的思路,视频里举的例子是小顶堆,大顶堆的做法也是差不多的。发现我视频里有一个口误,是降序排列,我中间不小心说成倒序排列了0.0

559ad34f9126422ece715b1723296733.png
堆排序实现思路讲解https://www.zhihu.com/video/1224798372403601408

归并排序

思路:归并排序分为两个部分。一部分是采用二分法,不断地划分数组,递归往下找要进行排序的数组。另一部分就是将二分法划分出来的两个序列进行归并排序。

这里进行归并排序的两个序列必须是已经排好序的,因为算法是直接去比较两个序列中的元素,将比较出来的较小值存入另一个用来暂时存数据的数组,再将较大值和【较小值那个序列的下一个元素】进行比较,就这样一直遍历下去直到某一序列被比较完,再将另一个序列剩下的元素存入暂时数组中,最后把暂时数组中的元素赋给原数组。

而前面的递归划分数组就能保证每次进入归并排序的两个序列是排好序的。

这样说感觉很抽象,看一下代码,自己演练一遍就明白了。

代码:

public 

总结:归并排序主要是利用完全二叉树的特性进行排序,时间复杂度是O(nlogn)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值