排序算法学习总结

排序算法学习总结

排序算法在经典算法里面是非常重要的,于是花了点时间将之前学习的常见的排序算法进行总结。

对于每种排序算法,需要理解以下问题:
1.算法思想是什么
2.时间复杂度
3.稳定性
4.什么情况下适用?

基于比较的排序,已证明,基于比较的排序算法时间复杂度不会低于O(nlgn)最好的情况能达到这个下限,包括:插入排序/希尔排序/选择排序/堆排序/冒泡排序/归并排序/快速排序

不是基于比较的排序算法有望将时间复杂度降到O(nlgn)以下,适当的作为补偿,待排序的序列也必须有一定的规律,包括:计数排序/基数排序/桶排序


插入排序

算法思想:从数组的第二个元素开始遍历整个数组。针对每个元素,依次将其前面的所有元素从后向前和进行比较,大于它的元素均向后移动,最后将该元素插入。

时间复杂度:O(n^2)。最好情况下,已经有序O(n),最坏情况下逆序O(n^2)

稳定性:稳定,原址排序

适用场景:当数组已经基本有序时,使用插入排序能有效减少移动的次数,时间消耗最少。


希尔排序

算法思想:也属于插入排序,直接插入排序在当序列恰好为顺序时,时间消耗为O(n),因此若某个序列已基本有序,直接插入排序的效率就会提高,基于这个思想,通过比较相距一定间隔的元素来工作,各趟比较所用距离随着算法的进行而减小,直至只比较相邻元素的最后一趟排序,因此也称递减增量排序算法。

时间复杂度:对插入算法的改进,低于O(n^2),具体与选择的增量序列有关

稳定性:不稳定,原址排序

使用场景:时间复杂度和增量序列的联系紧密,好的增量序列才能保证有好的时间复杂度,使用较少。


选择排序
算法思想:从所有序列中先找到最小的,然后放到第一个位置,之后再看剩余元素中最小的,放到第二个位置……以此类推

时间复杂度:O(n^2)

稳定性:不稳定,原址排序

适用场景:理解简单,比较元素较少时都可以使用,因为要遍历整个数组,任何情况下性能都很差。


堆排序

算法思想:也属于一种选择排序。由于一般的选择排序在寻找最大值时需要遍历数组,遍历数组的复杂度为O(n),因此造成了时间的浪费,如若将待排序的数组进行一系列整理,例如将其整理成有特点的堆这种数据结构,由于其删除最大值的复杂度仅仅为O(lgn),那么我们有理由相信,能将选择排序的时间复杂度降低到O(nlgn)

时间复杂度:O(nlgn)

稳定性:不稳定,原址排序

适用场景:没有特定的场景,只是没有快速排序用的多。


冒泡排序

算法思想:从第一个元素开始相邻的两个元素两两比较,按照小数在上大数在下的规则交换,一趟下去大数沉底。再从第一个元素开始两两比较相邻两个元素,直到倒数第二个元素....

时间复杂度:O(n^2),改进后再最好情况下达到O(n)

稳定性:不稳定,原址排序

适用场景:容易理解,比较元素较少时都可以使用。


归并排序

算法思想:分治思想,将数组分成两部分,如果这两部分均有序,那么便可在O(n)的时间内合并成一个完整的有序数组。由此,将区间划分下去,直到每个区间只有一个元素,即可认为已经有序,然后两两合并,而合并两个有序数组只需要O(n)的复杂度。

时间复杂度:O(nlgn)

稳定性:稳定,需要额外辅助空间

适用场景:同复杂度的的情况下可选,更多的用在外排序中。


快速排序

算法思想:分治思想,和归并排序相比,归并排序主要工作在于合并操作,而快速排序在于划分。划分数组为两部分,左边部分小于中间的值,右边部分大于中间的值,然后递归的对左右两边进行快速排序,这里,对数组的划分只需要O(n)的复杂度.

时间复杂度:O(nlgn),最差情况划分为1,n-1,此时复杂度为O(n^2)其他情况均为O(nlgn),期望为O(nlgn)

稳定性:不稳定,原址排序

适用场景:顾名思义,使用当然是最多的,整体情况下是最快的。


计数排序

算法思想:假设每个元素都是在0到k之间的一个整数。基数排序的基本思想,对于每个元素x,如果我们知道了小于x的元素的个数,就可以确定输出数组中元素x的位置,那么直接将元素x放到输出数组中。比如有3小于x的元素,那在输出数组中,x肯定位于第4个位置。

时间复杂度:O(k+n),当k小于等于n,也就是当k=O(n),k和n同阶时,时间复杂度为O(n)

稳定性:稳定,需要额外辅助空间

适用场景:元素都是在一个小的范围内的整数时可以考虑。


基数排序

算法思想:从最低为开始来排序的,从低位到高位,按位排序,按位排序必须是稳定的。

时间复杂度:O(d(n+k))

稳定性:稳定,需要辅助空间

适用场景:没有特定的场景,只是没有快速排序用的多。


桶排序

算法思想:假设输入数据服从均匀分布,然后将输入数据均匀地分配到有限数量的桶中,然后对每个桶再分别排序,对每个桶再使用插入排序算法,最后将每个桶中的数据有序的组合起来。

时间复杂度:O(d(n+k))

稳定性:稳定,需要辅助空间(链表)

适用场景:没有特定的场景。


稳定性记忆:只是换相邻的元素或者不交换元素的算法都是稳定的,需要交换不相邻的元素都是不稳定的算法,

posted @ 2015-11-20 16:09  浩荡乾坤  阅读(239)  评论(0编辑  收藏  举报