1、js的Array.sort()是使用什么算法排序;
1、火狐中是“归并排序”
2、V8引擎是 “插入排序和快速排序结合”。数组长度不超过10时,使用插入排序。长度超过10使用快速排序。在数组较短时插入排序更有效率。
2、各种算法
下图来自文章 各种排序实现以及稳定性分析
归并排序:
最好情况:O(nlogn)
最坏情况:O(nlogn)
平均情况:O(nlogn) 归并排序需要一个与原数组相同长度的数组做辅助来排序
空间复杂度:O(n)
稳定性:稳定(归并排序是稳定的排序算法,temp[i++] = arr[p1] <= arr[p2] ? arr[p1++] : arr[p2++];
这行代码可以保证当左右两部分的值相等的时候,先复制左边的值,这样可以保证值相等的时候两个元素的相对位置不变。)
冒泡排序
优点:比较简单,空间复杂度较低,是稳定的;
缺点:时间复杂度太高,效率慢;
选择排序
优点:一轮比较只需要换一次位置;
缺点:效率慢,不稳定(举个例子5,8,5,2,9 我们知道第一遍选择第一个元素5会和2交换,那么原序列中2个5的相对位置前后顺序就破坏了)。
插入排序
1、插入排序不适合对于数据量比较大的排序应用。
2、时间复杂度最好为o(n) 最坏为(n^2) 平均为o(n^2) 空间复杂度为o(1) 稳定
3、如果想把n个元素的序列升序排列,那么采用插入排序存在最好情况和最坏情况。最好情况就是,序列已经是升序排列了,在这种情况下,需要进行的比较操作需(n-1)次即可。最坏情况就是,序列是降序排列,那么此时需要进行的比较共有n(n-1)/2次。插入排序的赋值操作是比较操作的次数加上 (n-1)次。平均来说插入排序算法的时间复杂度为O(n^2)。
4、当n较大时,时间复杂度太大,因此插入排序的不适合大数据量的排序,一般来说适合小数据量排序,如n<1000,插入排序也作为快排的补充,v8中当n<10时,使用插排,否则使用快排。
快速排序
快速排序既不浪费空间速度又快,但不稳定
快速排序是通过一轮的排序将序列分割成独立的两部分,其中一部分序列的基准点(这里主要用值来表示)均比另一部分基准点小。继续对长度较短的序列进行同样的分割,最后到达整体有序。在排序过程中,由于已经分开的两部分的元素不需要进行比较,故减少了比较次数,降低了排序时间。
三个基本排序算法执行效率比较(冒泡排序,选择排序和插入排序)
从测试结果得到下面的表格:
Bubble | Selection | Insertion | Bubble/Selection | Bubble/Insertion | Selection/Insertion | |
1000 | 15 | 4 | 3 | 3.75 | 5 | 1.333333333 |
10000 | 1342 | 412 | 283 | 3.257281553 | 4.74204947 | 1.455830389 |
100000 | 125212 | 40794 | 27570 | 3.069372947 | 4.541603192 | 1.479651795 |
Avg | 3.358884833 | 4.761217554 | 1.422938506 |
忽略测试环境,因为三个算法都是在同一个环境中跑的, 可以得出如下结论:
1.冒泡算法效率最低。
2.插入算法效率最高。
3.选择算法是冒泡算法的3.3倍。
4.插入算法是冒泡算法的4.7倍。
5.插入算法是选择算法的1.4陪。