排序算法复杂度 排序算法

排序算法概述十大排序算法:冒泡排序,选择排序,插入排序,归并排序,堆排序,快速排序、希尔排序、计数排序,基数排序,桶排序
稳定 :如果a原本在b前面,而a=b,排序之后a仍然在b的前面;
不稳定 :如果a原本在b的前面,而a=b,排序之后a可能会出现在b的后面;
排序算法如果是稳定的,那么从一个键上排序,然后再从另一个键上排序,前一个键排序的结果可以为后一个键排序所用 。
算法的复杂度往往取决于数据的规模大小和数据本身分布性质 。
时间复杂度 : 一个算法执行所耗费的时间 。
空间复杂度 :对一个算法在运行过程中临时占用存储空间大小的量度 。
常见复杂度由小到大 :O(1)O(logn)O(n)O(nlogn)O(n^2)O(n^3)O(2^n)
在各种不同算法中,若算法中语句执行次数(占用空间)为一个常数,则复杂度为O(1);
当一个算法的复杂度与以2为底的n的对数成正比时,可表示为O(log n);
当一个算法的复杂度与n成线性比例关系时,可表示为O (n),依次类推 。
冒泡、选择、插入排序需要两个for循环,每次只关注一个元素,平均时间复杂度为
(一遍找元素O(n),一遍找位置O(n))
快速、归并、堆基于分治思想,log以2为底,平均时间复杂度往往和O(nlogn)(一遍找元素O(n),一遍找位置O(logn))相关
而希尔排序依赖于所取增量序列的性质,但是到目前为止还没有一个最好的增量序列。例如希尔增量序列时间复杂度为O(n2),而Hibbard增量序列的希尔排序的时间复杂度为,有人在大量的实验后得出结论;当n在某个特定的范围后希尔排序的最小时间复杂度大约为n^1.3 。
从平均时间来看,快速排序是效率最高的:
快速排序中平均时间复杂度O(nlog n),这个公式中隐含的常数因子很小,比归并排序的O(nlog n)中的要小很多,所以大多数情况下,快速排序总是优于合并排序的 。
而堆排序的平均时间复杂度也是O(nlog n),但是堆排序存在着重建堆的过程,它把根节点移除后,把最后的叶子结点拿上来后需要重建堆,但是,拿上的值是要比它的两个叶子结点要差很多的,一般要比较很多次,才能回到合适的位置 。堆排序就会有很多的时间耗在堆调整上 。
虽然快速排序的最坏情况为排序规模(n)的平方关系,但是这种最坏情况取决于每次选择的基准, 对于这种情况,已经提出了很多优化的方法,比如三取样划分和Dual-Pivot快排 。
同时,当排序规模较小时,划分的平衡性容易被打破,而且频繁的方法调用超过了O(nlog n)为
省出的时间,所以一般排序规模较小时,会改用插入排序或者其他排序算法 。
一种简单的排序算法 。它反复地走访过要排序的数列,一次比较两个元素,如果它们的顺序错误就把它们交换过来 。这个工作重复地进行直到没有元素再需要交换,也就是说该数列已经排序完成 。这个算法的名字由来是因为元素会经由交换慢慢“浮”到数列的顶端 。
1.从数组头开始,比较相邻的元素 。如果第一个比第二个大(小),就交换它们两个;
2.对每一对相邻元素作同样的工作,从开始第一对到尾部的最后一对,这样在最后的元素应该会是最大(小)的数;
3.重复步骤1~2,重复次数等于数组的长度,直到排序完成 。
首先,找到数组中最大(小)的那个元素;
其次,将它和数组的第一个元素交换位置(如果第一个元素就是最大(小)元素那么它就和自己交换);
再次,在剩下的元素中找到最大(小)的元素,将它与数组的第二个元素交换位置 。如此往复,直到将整个数组排序 。
这种方法叫做选择排序,因为它在不断地选择剩余元素之中的最大(小)者 。
对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入 。
为了给要插入的元素腾出空间,我们需要将插入位置之后的已排序元素在都向后移动一位 。
插入排序所需的时间取决于输入中元素的初始顺序 。例如,对一个很大且其中的元素已经有序(或接近有序)的数组进行排序将会比对随机顺序的数组或是逆序数组进行排序要快得多 。
总的来说,插入排序对于部分有序的数组十分高效,也很适合小规模数组 。
一种基于插入排序的快速的排序算法 。简单插入排序对于大规模乱序数组很慢,因为元素只能一点一点地从数组的一端移动到另一端 。例如,如果主键最小的元素正好在数组的尽头,要将它挪到正确的位置就需要N-1 次移动 。

秒懂生活扩展阅读