资讯专栏INFORMATION COLUMN

常用的js排序算法

guyan0319 / 1806人阅读

摘要:假设要对数组进行归并排序,步骤是先将划分为两个数组和即把数组从中间分开再分别对数组重复步骤的操作,逐步划分,直到不能再划分为止每个子数组只剩下一个元素,这样,划分的过程就结束了。

插入排序

算法描述:

从第一个元素开始,该元素可以认为已经被排序

取出下一个元素,在已经排序的元素序列中从后向前扫描

如果该元素(已排序)大于新元素,将该元素移到下一位置

重复步骤 3,直到找到已排序的元素小于或者等于新元素的位置

将新元素插入到该位置后

重复步骤 2~5

var arr = [5, 6, 3, 1, 8, 7, 2, 4];
for(let i = 1;i= 0 ; j -- ){
        console.log("单次比较数据:"+arr[myIndex]+"---"+arr[j])
        if(arr[myIndex] < arr[j]){
            [arr[myIndex],arr[j]] = [arr[j],arr[myIndex]];
            myIndex = j;
        }else{
          break;
        }
        console.log("数组"+arr);
    }
}

时间复杂度 O(n^2)
运行过程

选择排序

算法描述

直接从待排序数组中选择一个最小(或最大)数字,放入新数组中。

假定第一个数字是最小的,然后依次和后面的比较,哪个小哪个就记录当前那个的下标。

记录完下标了之后替换第一个和那个最小数字的位置

依次执行上述步骤,只不过最小的位置依次累加

var arr = [5, 6, 3, 1, 8, 7, 2, 4];
for(let i = 0; i < arr.length - 1;i++){
    console.log("次数"+Number(i+1))
    let minIndex = i;
    for(let j = i ;j < arr.length - 1; j++){
         console.log("单次比较数据:"+arr[minIndex]+"---"+arr[j+1])
         if(arr[minIndex] > arr[j+1]){
            minIndex = j+1;
         }
    }
    [arr[minIndex],arr[i]] = [arr[i],arr[minIndex]];
    console.log("数组"+arr);

}

时间复杂度 O(n^2)

运行过程

冒泡排序

就几种算法来看,感觉冒泡是比较慢的

算法描述:

比较相邻的元素。如果第一个比第二个大,就交换他们两个。

对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。

针对所有的元素重复以上的步骤,除了最后一个。

持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。

var arr = [5, 6, 3, 1, 8, 7, 2, 4];
let count = 0;
for(let i = arr.length ; i > 0; i --){
    console.log("次数"+i);
    for(let j = 1; j < i; j ++){
        console.log("单次比较数据:"+arr[j]+"----"+arr[j-1])
        if(arr[j] < arr[j-1]){
            [arr[j],arr[j-1]] = [arr[j-1],arr[j]]
        }
    }
    console.log(arr);
}

时间复杂度 O(n^2)

运行过程

归并排序

归并排序的图可能一下看不懂,是因为图代表的是运行的过程,主要看算法描述

归并排序:其基本思想是分治策略,先进行划分,然后再进行合并。
假设要对数组C进行归并排序,步骤是:
1.先将C划分为两个数组A和B(即把数组C从中间分开)
2.再分别对数组A、B重复步骤1的操作,逐步划分,直到不能再划分为止(每个子数组只剩下一个元素),这样,划分的过程就结束了。
如: [12 20 30 21 15 33 26 19 40 25]
划分为: [12 20 30 21 15] [33 26 19 40 25]

       [12 20]      [30 21 15]       [33 26]       [19 40 25]
     [12]  [20]   [30]  [21 15]     [33]  [26]    [19]    [40 25]
     [12]  [20]   [30] [21] [15]    [33]  [26]    [19]   [40] [25]

3.然后从下层往上层不断合并数组,每一层合并相邻的两个子数组,合并的过程是每次从待合并的两个子数组中选取一个最小的元素,然后把这个元素放到合并后的数组中,不断重复直到把两个子数组的元素都放到合并后的数组为止。
4.依次类推,直到合并到最上层结束,这时数据的排序已经完成了。

var arr = [5, 6, 3, 1, 8, 7, 2, 4,9];
function mergeSort(arr){
    if(arr.length === 1){
        return arr;
    }
    let midIndex = Math.floor(arr.length / 2);
    let leftArr = arr.slice(0,midIndex);
    let rightArr = arr.slice(midIndex);
    console.log("拆分数组"+leftArr+"------"+rightArr)
    return mergeFn(mergeSort(leftArr),mergeSort(rightArr));
}.
function mergeFn(left,right){
    let tmp = [];
    console.log(left + "----" + right);
    while (left.length && right.length) {
        console.log("单次比较数据:"+left[0]+"和"+right[0]+"谁小谁所在的数组就被shift掉一个")
        if (left[0] < right[0]){
          tmp.push(left.shift());
        }
        else{
          tmp.push(right.shift());
        }
        console.log(tmp);
    }
    let arra = tmp.concat(left, right);
    console.log("本次比较完毕:"+arra);

    return arra;

}
mergeSort(arr);

时间复杂度 O(nlogn)

运行过程,看了运行过程就能看懂图了,也知道js函数里的参数有函数的情况下的执行顺序是自左向右

快速排序

图上的运行方式是按照基准是第0号位算的,看起来稍微有点乱,不过只要知道快排是怎么算的就好了

算法描述:

在数据集之中,选择一个元素作为”基准”(pivot)。

所有小于”基准”的元素,都移到”基准”的左边;所有大于”基准”的元素,都移到”基准”的右边。这个操作称为分区 (partition)操作,分区操作结束后,基准元素所处的位置就是最终排序后它的位置。

对”基准”左边和右边的两个子集,不断重复第一步和第二步,直到所有子集只剩下一个元素为止。

var arr = [5, 6, 3, 1, 8, 7, 2, 4];
function quickSort(arr){
    if(arr.length <= 1){
        return arr;
    }
    //找基准
    let midIndex = Math.floor(arr.length/2);
    //剔除基准值
    let midNum = arr.splice(midIndex,1)[0];
    console.log("基准值:"+midNum);
    let leftArr = [],rightArr=[];
    for(let i = 0 ; i < arr.length; i++){
        //小于基准的进左边,大于的进右边
        arr[i] < midNum ? leftArr.push(arr[i]) : rightArr.push(arr[i])
    }
    console.log("小于基准值的数组:"+leftArr);
    console.log("大于基准值的数组:"+rightArr);
    return quickSort(leftArr).concat(midNum,quickSort(rightArr));
}
quickSort(arr);

时间复杂度 O(nlogn)

运行过程

这个运行过程是按照基准为0号位算的;

总结

可以看到,快速排序和归并排序是比较快。而且快排更容易理解更好写一些。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/94704.html

相关文章

  • js算法之最常用排序

    摘要:算法之最常用的排序参加百度前端的课程真的是好多知识点不知道。快速排序也是在实际中最常用的一种排序算法,速度快,效率高。插入排序的思路很简单,很清晰,是一种最常见最简单的排序方法。 js算法之最常用的排序 参加百度前端的课程真的是好多知识点不知道。边学边做题,在问题中学习,知识点从点到面,但是要善于总结记录才行。加油吧,骚年! 可视化排序网站 时间复杂度是衡量一个算法效率的基本方法我们把...

    宠来也 评论0 收藏0
  • 【面试篇】JS常用排序算法

    摘要:冒泡排序每次对比相邻两个数据的大小升序小的拍前面,若前一个数比后一个数大,则交换两数位置。 冒泡排序:每次对比相邻两个数据的大小,升序小的拍前面,若前一个数比后一个数大,则交换两数位置。需要两次for循环遍历. 优点:简单 缺点:时间复杂度高,运行效率低下 function sortArr(arr){ var temp; for(var i=0;i

    YanceyOfficial 评论0 收藏0
  • JS数据结构与算法_排序和搜索算法

    摘要:上一篇数据结构与算法树写在前面这是学习数据结构与算法的最后一篇博客,也是在面试中常常会被问到的一部分内容排序和搜索。 上一篇:JS数据结构与算法_树 写在前面 这是《学习JavaScript数据结构与算法》的最后一篇博客,也是在面试中常常会被问到的一部分内容:排序和搜索。在这篇博客之前,我每每看到排序头就是大的,心里想着类似冒泡排序,两层遍历啪啪啪就完事了,然后再也无心去深入研究排序相...

    姘搁『 评论0 收藏0
  • Deep in JS - 收藏集 - 掘金

    摘要:今天同学去面试,做了两道面试题全部做错了,发过来给道典型的面试题前端掘金在界中,开发人员的需求量一直居高不下。 排序算法 -- JavaScript 标准参考教程(alpha) - 前端 - 掘金来自《JavaScript 标准参考教程(alpha)》,by 阮一峰 目录 冒泡排序 简介 算法实现 选择排序 简介 算法实现 ... 图例详解那道 setTimeout 与循环闭包的经典面...

    enali 评论0 收藏0

发表评论

0条评论

guyan0319

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<