Java基础——常见的排序算法

一、插入算法

举个例子,我们军训时,教官已经喊同学们排队了,这时你迟到了你需要插入到队列里,队列按照高矮顺序排列,你不知道你该在哪你就与队列中的同学依次比较身高,如果这个同学比你高,就把这个同学向后位移一个位置,否则你就插入到这个同学后面的一个位置,这就是插入排序。

时间复杂度:直接插入排序平均时间复杂度为 O(n^2) ,最好时间复杂度为 O(n) ,最坏时间复杂度为 O(n^2) 。

空间复杂度:直接插入排序使用了常数空间,空间复杂度为 O(1) 。

二、冒泡排序法

这是一种简单的排序算法,接着上个例子,你需要进入到队伍,不过这时队伍原本也没与排列好。你就随便站在了一个位置,然后和边上的人比较,如果他比你高你就和他换位置然后再和下一个人比较,和你换完位置的同学也会比较,每两个相邻的相比较,矮的往前站,高的往后换直到排列整齐。

时间复杂度:冒泡排序平均时间复杂度为 O(n^2) ,最好时间复杂度为 O(n) ,最坏时间复杂度为
O(n^2) 。

空间复杂度:冒泡排序使用了常数空间,空间复杂度为O(1)

三、选择排序(不稳定)

还是军训列队,这次你没有迟到,教官还没来,你和你同学正在一起聊天,这时教官来了喊你们站好,你们就原地站好了,教官来为你们排序,他先依次比较找到最矮的人然后放在队伍最前面,然后再依次比较找到最矮的那个放在第二位以此类推,直到队伍排列完毕。

时间复杂度:冒泡排序平均时间复杂度为 O(n^2) ,最好时间复杂度为 O(n^2) ,最坏时间复杂度为 O(n^2) 。

空间复杂度:简单选择排序使用了常数空间,空间复杂度为O(1)。

四、希尔排序(不稳定)

1959年 Shell 发明,第一个突破 O(n^2) 的排序算法,是直接插入排序的改进版。它与直接插入排序的不同之处在于,它会优先比较距离较远的元素。希尔排序又叫缩小增量排序。

排序方法:先将整个待排元素序列分割成 gap 个增量为 gap 的子序列(每个子序列由位置相差为 gap 的元素组成,整个序列正好分割成 gap 个子序列,每个序列中有 n / gap 个元素)分别进行直接插入排序,然后缩减增量为之前的一半再进行排序,待 gap == 1时,希尔排序就变成了直接插入排序。因为此时序列已经基本有序,直接插入排序在元素基本有序的情况下(接近最好情况),效率是很高的。gap初始值一般取 len / 2。

希尔排序平均时间复杂度为 O(nlogn),最好时间复杂度为 O(nlog2n),最坏时间复杂度为O(nlog2n)。希尔排序的时间复杂度与增量序列的选取有关。

空间复杂度:希尔排序使用了常数空间,空间复杂度为O(1)。

五、堆排序

我们先来介绍一下堆的概念:堆是一种完全二叉树,且满足所有父节点的值均大于等于(或小于等于)其子节点的值。

排序方法:因为堆遵循有父节点的值均大于等于(或小于等于)其子节点的值,我们可以将要排列的数据构建成大(小)顶堆,将每个父节点与子节点进行比较,根据堆的原理不停地进行调换子节点和父节点的位置,直到达到大(小)顶堆的原理,完成排序。

时间复杂度:堆排序平均时间复杂度为 O(nlogn) ,最好时间复杂度为 O(nlogn) ,最坏时间复杂度为 O(nlogn) 。堆排序的形式就是一棵二叉树,它需要遍历的次数就是二叉树的深度,而根据完全二叉树的可以得出它在任何情况下时间复杂度均是 O(nlogn) 。

空间复杂度:堆排序使用了常数空间,空间复杂度为O(1)。

六、归并排序

排序方法:归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为2-路归并。

时间复杂度:归并排序平均时间复杂度为 O(nlogn) ,最好时间复杂度为 O(nlogn) ,最坏时间复杂度为O(nlogn) 。归并排序的形式就是一棵二叉树,它需要遍历的次数就是二叉树的深度,而根据完全二叉树的可以得出它在任何情况下时间复杂度均是 O(nlogn) 。

空间复杂度:归并排序空间复杂度为 O(n)

posted @ 2020-03-13 17:14  spider_jx  阅读(216)  评论(0编辑  收藏  举报