常用排序(稳定性、时间/空间复杂度)
2016-03-23 00:29
225 查看
一、稳定性
排序算法的稳定性通俗地讲就是能保证排序前2个相等的数其在序列的前后位置顺序和排序后它们两个的前后位置顺序相同。稳定性的好处。排序算法如果是稳定的,那么从一个键上排序,然后再从另一个键上排序,第一个键排序的结果可以为第二个键排序所用。
以上三种排序具体原理及代码实现:常用排序(冒泡、快速、选择)
1、冒泡排序(稳定)
冒泡排序是比较相邻两个元素的值的大小,当相邻元素的值相等时,这两个元素不会交换位置,因此冒泡排序不会改变相等元素的前后位置,所以是稳定的。
2、快速排序(不稳定)
快速排序需要指定一个基准数,两个指针i,j,当i和j相遇时就会交换此时i,j所共同指向的那个位置的元素A[i](A[j])与基准数,这时就很容易发生相等元素前后位置的调换了。比如,7,3,3,4,3,8,9这个序列,当一次排序最后,就会调换中间3于基准数7的位置,所以不稳定。
3、选择排序(不稳定)
选择排序是每次选择一个最大的元素放在数组的倒数第i个位置上,所以当有相等的元素时,就会造成前后顺序改变的情况,因此是选择排序是不稳定的。
以下三种排序具体原理及代码实现:常用排序(插入、堆、归并)
4、插入排序(稳定)
插入排序分为已经排序的部分和未排序的序列,初始时A[0]就是一个已经排序的序列,A[1]~A
是未排序部分,之后每次将未排序序列中一个元素插入到已排序的序列中的适当位置,所以此排序也不会打乱相等元素的顺序,是稳定的。
5、堆排序(不稳定)
(就大顶堆而言)堆是每个父节点大于其左右子节点的二叉树,堆排序时如果一个父节点的左子节点与其相等,而其右子节点大于此父节点,则会导致父节点与这个右子节点交换,因而堆排序是不稳定的。
6、归并排序(稳定)
7、基数排序(稳定)
8、希尔排序(shell) (不稳定)
二、时间/空间复杂度
注:log底数默认为2xxxx | 最差时间复杂度 | 平均时间复杂度 | 空间复杂度 |
---|---|---|---|
冒泡排序 | O(n2) | O(n2) | O(1) |
快速排序 | O(n2) | O(n*logn) | O(logn)~O(n) |
选择排序 | O(n2) | O(n2) | O(1) |
插入排序 | O(n2) | O(n2) | O(1) |
堆排序 | O(n*logn) | O(n*logn) | O(1) |
归并排序 | O(n*logn) | O(n*logn) | O(n) |
快速排序比大部分排序算法都要快。尽管我们可以在某些特殊的情况下写出比快速排序快的算法,但是就通常情况而言,没有比它更快的了。快速排序是递归的,空间复杂度较高,不适合内存非常有限的机器。
插入排序是对冒泡排序的改进。它比冒泡排序快2倍。
堆排序适合于数据量非常大的场合(百万数据)。
归并排序算法比较占用内存,但却是效率高且稳定的排序算法。
Shell排序比冒泡排序快5倍。Shell排序比起快速排序,堆排序,归并排序慢很多,但它对于数据量较小的数列重复排序是非常适合的。
相关文章推荐
- 一款面试复习应用源码
- 滥用单例
- Mathematica 中 Minimize函数无法找到全局最小值时的解决方法
- 控制表单内容字段必填项的一种设计思路
- 当你访问淘宝的时候,发生了什么?
- Git 教程索引
- 第七届蓝桥杯c/c++ C组部分题解
- ThinkPHP 分页类
- 227. Basic Calculator II | Java最短代码实现
- C++拷贝构造函数
- ubuntu运行android studio出错unable to run mksdcard sdk tool
- epoll的高效实现原理
- 滑雪(记忆化)
- C++ return语句
- BigInteger(HDU1002)和BigDecimal处理
- hdu 5171 fib矩阵快速幂
- Codeforces 300C Beautiful Numbers 【组合数学】
- Codeforces Round #345 (Div. 1) E - Clockwork Bomb
- 【c++】字符串循环左移
- android中很多情况下我们需要会使用多个fragment,我们这时就需要一个showFragment来实现fragment之间的切换