阿里面试中有一道题是这样的:

                请用JavaScript语言实现 sort 排序函数,要求:sort([5, 100, 6, 3, -12]) // 返回 [-12, 3, 5, 6, 100],如果你有多种解法,请阐述各种解法的思路及优缺点。(仅需用代码实现一种解法,其它解法用文字阐述思路即可)

那我们就来看一下各种解法的思路以及优缺点~

简单排序

1冒泡法:

原理:对存放原始数据的数组,按从前往后的方向进行多次扫描,每次扫描称为一趟。当发现相邻两个数据的次序与要求的不同时,即将两个数据进行互换,第一次扫描结束后,进行第二次扫描,直到所有数据符合要求。

优点:

平均时间复杂度O(n*n),是比较容易实现的算法,相对稳定。

缺点:

慢,每次只能移动相邻两个数据

 var sortArray=new Array();
var temp;
sortArray=id_list.split(":");
for(var i=;i<sortArray.length;i++)
{
for(var j=;j<i;j++)
{ if(parseInt(sortArray[j])>parseInt(sortArray[i]))
{
temp=sortArray[j];
sortArray[j]=sortArray[i];
sortArray[i]=temp;
}
}
}

2插入排序:
原理:首先新建一个空列表用于保存已经排序的有序数列A,从原序列B中取出一个数,逐个与有序列表中的数比较,如果b[0]大于a[0]则跳过,继续比较b[0]与a[1],如果前者仍大于后者,则继续跳过,直到b[0]小于a[x],则将b[0]插入到a[x]的位置,a[x]及其后面的往后移动一位。使其仍旧保持有序状态。然后再取出一个数按相同方法插入,直至原数列为空。它借助了“逐步扩大成果”的思想,使有序列表的长度逐渐增长,直至等于元列表的长度即排序完成。

优点:

容易实现,稳定,快,适合少量数据比较。时间复杂度为O(n*n)。

缺点:

效率不高,比较次数不一定,比较次数越少,插入点后的数据移动越多,如果数据量庞大的话,可以使用链表来解决这个问题~

 function insertSort(){
var A=[,,,,,]; document.write("原数组:")
for (var n = ; n < A.length; n++) {
document.write(A[n] + " ");
}
document.write("原数组长度:"+A.length+"<br/>");
var key;
var i;
for(var j=;j<A.length;j++){
key=A[j];
i=j-;
while(i>-&&A[i]>key){
A[i+]=A[i];
i=i-;
}
A[i+]=key; //输出结果
document.write("第" + j + "遍排序的结果是:")
for (var n = ; n < A.length; n++) {
document.write(A[n] + " ");
}
document.write("<br />")
}
}

3选择排序

原理:每一趟从待排序的数据元素中选出最小(或最大)的一个元素,顺序放在已排好的数列的最后,直到全部待排序的数据元素排完。

优点:进行(n-1)趟排序即可排序完成,时间复杂度为n的平方O(n*n)

缺点:比较次数比较多,每一趟从数据中选出的目标数据都是和剩下所有数据比较的结果。

*注意和冒泡排序的区别 选择排序是从一个序列到另一个序列,冒泡排序是在本身序列的排序,选择排序性能稍稍好于冒泡排序。

    function selectSort(array) {
var min, temp; ;
for (var i = 0; i < array.length; i++) {
min = i;
for (var j = i + 1; j < array.length; j++) {
if (array[min] > array[j])
min = j;
}
if (min != i) {
temp = array[i];
array[i] = array[min];
array[min] = temp;
}
/* 输出结果 */
document.write("第 + i + "遍排序的结果是:")
for (var n = 0; n < array.length; n++) {
document.write(array[n] + ",");
} document.write("<br />")
/* 输出结果结束 */ }
}

高效排序

快速排序

原理:快速排序是目前已知速度最快的排序方法,,排序方法所运用的思想和我们众所周知的二分法一脉相承,专业一点的话称为“分治策略”。保证列表的前半部分都小于后半部分,然后分别对两部分进行排序,这样比较前半部分时就不需要和后半部分比较了,这种方法大大减少了数据间的不必要排序,因而高效~具体步骤:假设要对一组数据进行升序排列,先任取数据a[x]作为基准,,比较a[x]与其他数据并排序,使a[x]排在数据的第k位,并且使a[1]~a[k-1]中的每一个数据都小于a[x],a[k+1]~a[n]中的每一个数据都大于a[k],然后按同样的方法对两组数据进行快速排序。

优点:速度极快,数据移动较少 平均时间复杂度为(n*log n)

缺点:不稳定

   var count = 0;
function quickSort(array, low, high) {
var temp; if (low < high) { var keypoint = QuickSortHelp(array, low, high);
count++;
document.write("<br />第台? + count + "遍括?排?序ò的?结á果?是?:")
for (var l = 0; l < array.length; l++) {
document.write(array[l] + ",");
}
quickSort(array, low, keypoint - 1);
quickSort(array, keypoint + 1, high); }
}
function QuickSortHelp(array, low, high) {
while (low < high) { while (low < high && array[low] <= array[high]) {
high--;
}
temp = array[low];
array[low] = array[high];
array[high] = temp;
while (low < high && array[low] <= array[high]) {
low++
}
temp = array[low];
array[low] = array[high];
array[high] = temp; }
return low;
}

归并排序:

原理:归并排序是多次将两个或两个以上的有序表合并成一个新的有序表。特点是相等的元素的顺序不会改变,这对要排序数据包含多个信息按其中的某一个信息排序,要求其他信息尽量按输入的顺序排列时很重要,这也是比快速排序优势的地方。归并排序对数据的有序性不敏感,其时间复杂度在任何情况下都是O(nlog 2n),所以如果数据节点数据量大的话不是很合适。但是如果改造成索引操作的话效果还是很棒的~

优缺点在原理中说明~

//source源数组
//dest目标数组
//s起始下标
//t目标下标
function mSort(source, dest, s, t) {
6 var m; //取中间值
var dest2 = new Array();
if (s == t) {
dest[s] = source[s]; }
else {
m = Math.floor((s + t) / 2);
mSort(source, dest2, s, m);
mSort(source, dest2, m+1 , t);
merge(dest2, dest, s, m, t);
/* 输出结果 */
document.write("<br />第 + ++count + "遍排序的结果是:")
for (var n = 0; n < dest.length; n++) {
document.write(array[n] + ",");
}

} } 27
//source原数组
//dest排序后的数组
//s第一个下标
//m第二个数组下标
function merge(source, dest, s, m, n) {
for (var j = m+1, k = s; j <= n && s <= m; k++) {
if (source[s] < source[j]) {
dest[k] = source[s++];
}
else {
dest[k] = source[j++];
}
} //将剩余排不完的有序数组加入到dest的末端
if (s <= m) {
for (var l = 0; l <= m - s; l++) {
dest[k + l] = source[s+l];
}
}
if (j <= n) {
for (var l = 0; l <= n - j; l++) {
dest[k + l] = source[j+l];
} }
}

堆排序:

原理:首先新建一个空列表,在带排序数列中找到最大的数字,将其加在空列表的末尾,并将其从原数列中删除,重复以上步骤,直至原数列为空。

*请注意与插入排序的区别,堆排序时间复杂度为O(nlog n),插入排序为O(n*n),堆排序新建的空列表作用与插入排序新建的有序列表作用相同,但仅仅是作用相同。

优点:效率高,如果只是要找到最大数的话时间复杂度仅仅为O(1)

缺点:实现相对复杂

 function heapSort(array) {
var temp;
var i;
for (i = Math.floor(array.length / 2); i >= 0; i--) {
heapAdjust(array, i, array.length - 1); //将数组array构建成一个大顶堆
}
for (i = array.length - 1; i >= 0; i--) {
/*把根节点交换出去*/
temp = array[i];
array[i] = array[0];
array[0] = temp; /*余下的数组继续构建成大顶堆*/
heapAdjust(array, 0, i - 1);
/* 输出结果 */
document.write("<br />第 + (array.length - i).toString() + "遍排序的结果是:")
for (var n = 0; n < array.length; n++) {
document.write(array[n] + ",");
}
/* 输出结果结束 */
}
}
//要调整的子树
//start为数组开始下标
//max是数组结束下标
function heapAdjust(array, start, max) {
var temp, j;
temp = array[start];//temp是根节点的值
for (j = 2 * start; j < max; j *= 2) {
if (j < max && array[j] < array[j + 1]) { //取得较大孩子的下标
++j; }
if (temp >= array[j])
break;
array[start] = array[j];
start = j;
}
array[start] = temp; }

*该代码部分借鉴CareySon

Javascript中的冒泡排序,插入排序,选择排序,快速排序,归并排序,堆排序 算法性能分析的更多相关文章

  1. JavaScript数组排序(冒泡排序、选择排序、桶排序、快速排序)

    * 以下均是以实现数组的从小到大排序为例 1.冒泡排序 先遍历数组,让相邻的两个元素进行两两比较 .如果要求小到大排:最大的应该在最后面,如果前面的比后面的大,就要换位置: 数组遍历一遍以后,也就是第 ...

  2. Java中的冒泡排序和选择排序

    //冒泡排序 public class Test5 { public static void main(String[] args) { int[] arr = {12,2,25,89,5}; bub ...

  3. php中的冒泡排序和选择排序d

    //冒泡算法 //定义一个数组  $arr=arr{2,5,1155,3,8}; $len=count($arr); for($i=0;$i<$len-1;$i++) //定义以下需要宣传的次数 ...

  4. C++/C实现各种排序算法(持续更新)--冒泡排序,选择排序,归并排序

    2018 3 17 今日总结一下C++中的排序算法: 1冒泡排序 它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来.走访数列的工作是重复地进行直到没有再需要交换,也就是 ...

  5. js中常见的数组排序算法-冒泡排序和选择排序

    reverse( )  数组逆序   // reverse() 数组逆序 var arr = ["边境牧羊犬", "德国牧羊犬", "金毛" ...

  6. 冒泡排序、选择排序、直接插入排序、快速排序、折半查找>从零开始学JAVA系列

    目录 冒泡排序.选择排序.直接插入排序 冒泡排序 选择排序 选择排序与冒泡排序的注意事项 小案例,使用选择排序完成对对象的排序 直接插入排序(插入排序) 快速排序(比较排序中效率最高的一种排序) 折半 ...

  7. JavaScript算法(冒泡排序、选择排序与插入排序)

    冒泡排序.选择排序与插入排序复杂度都是二次方级别的,放在一起说吧. 介绍一些学习这三个排序方法的比较好的资料.冒泡排序看<学习JavaScript数据结构与算法>介绍的冒泡排序,选择排序看 ...

  8. php排序介绍_冒泡排序_选择排序法_插入排序法_快速排序法

    这里我们介绍一些常用的排序方法,排序是一个程序员的基本功,所谓排序就是对一组数据,按照某个顺序排列的过程. 充效率看 冒泡排序法<选择排序法<插入排序法 排序分两大类: 内部排序法 交换式 ...

  9. Java数据结构和算法总结-冒泡排序、选择排序、插入排序算法分析

    前言:排序在算法中的地位自然不必多说,在许多工作中都用到了排序,就像学生成绩统计名次.商城商品销量排名.新闻的搜索热度排名等等.也正因为排序的应用范围如此之广,引起了许多人深入研究它的兴趣,直至今天, ...

随机推荐

  1. 自定义使用AVCaptureSession 拍照,摄像,载图

    转载自 http://blog.csdn.net/andy_jiangbin/article/details/19823333 拍照,摄像,载图总结 1 建立Session  2 添加 input  ...

  2. HDU 5441 Travel (并查集+数学+计数)

    题意:给你一个带权的无向图,然后q(q≤5000)次询问,问有多少对城市(城市对(u,v)与(v,u)算不同的城市对,而且u≠v)之间的边的长度不超过d(如果城市u到城市v途经城市w, 那么需要城市u ...

  3. jeecms附件标签用法

    [#if content.attachments?size gt 0] [#list content.attachments as attach] <a id="attach${att ...

  4. web.xml文件中配置ShallowEtagHeaderFilter需注意的问题

    问题现象及解决方法 今天在Spring MVC应用中加入ShallowEtagHeaderFilter时,发现返回的响应中没有etag头,上网查了很多相关资料,也试了很多方法依然不起作用.在查看web ...

  5. Java学习笔记(三):数组

    数组声明 java语言中,数组是一种最简单的复合数据类型.数组是有序数据的集合,数组中的每个元素具有相同的数据类型,可以用一个统一的数组名和下标来唯一地确定数组中的元素. int arr1[]; in ...

  6. ADO.NET 快速入门(十一):连接池

    这个示例演示了如何构建一个到数据源的连接池.你可以通过连接池部署高性能的应用程序.本例中使用连接串创建连接池,并且由 SqlConnection 自动管理.   string connString; ...

  7. java中hashcode和equals的区别和联系

    HashSet和HashMap一直都是JDK中最常用的两个类,HashSet要求不能存储相同的对象,HashMap要求不能存储相同的键. 那么Java运行时环境是如何判断HashSet中相同对象.Ha ...

  8. Codeforces Round #115 A. Robot Bicorn Attack 暴力

    A. Robot Bicorn Attack Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/17 ...

  9. Codeforces Round #250 (Div. 1) B. The Child and Zoo 并查集

    B. The Child and Zoo Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/438/ ...

  10. seajs 2.3.0 加入jquery

    [前言] 上篇文章简单的介绍了seajs的使用,下午使用seajs整合jquery就碰到问题了. 下载seajs上的examples,里面直接require('jquery')没有不论什么问题, 我照 ...