参考文章:

1. 冒泡排序

思路

  • 比较所有相邻元素,如果第一个比第二个大,则交换它们
  • 一轮下来,可以保证最后一个数是最大的
  • 执行n-1轮,就可以完成排序

代码

  1. Array.prototype.bubbleSort = function () {
  2. for (let i = 0; i < this.length - 1; i++) {
  3. let hasSwapped = false // 本轮是否有交换行为
  4. for (let j = 0; j < this.length - 1 - i; j++) {
  5. if (this[j] > this[j + 1]) {
  6. hasSwapped = true
  7. const temp = this[j]
  8. this[j] = this[j + 1]
  9. this[j + 1] = temp
  10. }
  11. }
  12. // 若本轮没有交换行为,则无需再进行下一轮遍历
  13. if (!hasSwapped) {
  14. break;
  15. }
  16. }
  17. }
  18. const arr = [5, 4, 3, 2, 1]
  19. arr.bubbleSort()
  20. console.log('arr', arr)

分析

  • 时间复杂度:

    • 最好:O(n)【已排好序的数组,没有交换,一轮遍历完成】
    • 最坏:O(n2)
    • 平均:O(n2)
  • 空间复杂度:O(1)
  • 排序方式:In-place
  • 稳定性:稳定

2. 选择排序

思路

  • 找到数组中的最小值(用indexMin来表示当前值下标,遍历遇到更小的就替换为它),将其放置在第一位(和原第一位交换)
  • 接着找到第二小的值,选中它并将其放置在第二位
  • 以此类推,执行n-1轮

代码

  1. Array.prototype.selectionSort = function () {
  2. for (let i = 0; i < this.length - 1; i++) {
  3. let indexMin = i
  4. for (let j = i; j < this.length; j++) {
  5. if (this[j] < this[indexMin]) {
  6. indexMin = j
  7. }
  8. }
  9. // 若当前位就是最小位,则不交换
  10. if (indexMin !== i) {
  11. const temp = this[i]
  12. this[i] = this[indexMin]
  13. this[indexMin] = temp
  14. }
  15. }
  16. }
  17. const arr = [5, 4, 3, 2, 1]
  18. arr.selectionSort()
  19. console.log('arr', arr)

分析

  • 时间复杂度:

    • 最好:O(n2)
    • 最坏:O(n2)
    • 平均:O(n2)
  • 空间复杂度:O(1)
  • 排序方式:In-place
  • 稳定性:不稳定

3. 插入排序

思路

  • 将一个元素插入到前面排序的子序列中,使插入后的子序列仍然是排序的,n个元素共需n-1趟
  • 从第二个数开始往前比,比他大就往后排,以此类推进行到最后一个数

代码

  1. Array.prototype.insertionSort = function () {
  2. for (let i = 1; i < this.length; i++) {
  3. const num = this[i];
  4. for (let j = i - 1; j >= 0; j--) {
  5. if (num < this[j]) {
  6. this[j + 1] = this[j]
  7. }
  8. else {
  9. break
  10. }
  11. }
  12. this[j + 1] = num
  13. }
  14. }
  15. const arr = [5, 4, 3, 2, 1]
  16. arr.insertionSort()
  17. console.log('arr', arr)

分析

  • 时间复杂度:

    • 最好:O(n)
    • 最坏:O(n2)
    • 平均:O(n2)
  • 空间复杂度:O(1)
  • 排序方式:In-place
  • 稳定性:稳定

4. 归并排序

思路

  • 分:把数组劈成两半,再递归地对子数组进行“分”操作,直到分成一个个单独的数
  • 合:把两个数合并为有序数组,再对有序数组进行合并,直到全部子数组合并为一个完整数组
    • 合并两个有序数组

      • 新建一个空数组res,用于存放最终排序后的数组
      • 比较两个有序数组的头部,较小者出队并推入res中
      • 如果两个数组还有值,就重复第二步

代码

  1. Array.prototype.mergeSort = function () {
  2. // 终点
  3. if (this.length === 1) {
  4. return this
  5. }
  6. // 分
  7. const mid = Math.floor(this.length / 2)
  8. const left = this.slice(0, mid)
  9. const right = this.slice(mid)
  10. left.mergeSort()
  11. right.mergeSort()
  12. // 合
  13. let res = []
  14. while (left.length > 0 || right.length > 0) {
  15. if (left.length > 0 && right.length > 0) {
  16. left[0] < right[0] ? res.push(left.shift()) : res.push(right.shift())
  17. }
  18. else if (left.length > 0) {
  19. res.push(left.shift())
  20. } else {
  21. res.push(right.shift())
  22. }
  23. }
  24. // res 拷贝到 this
  25. res.forEach((item, i) => {
  26. this[i] = item
  27. })
  28. }
  29. const arr = [5, 4, 3, 2, 1]
  30. arr.mergeSort()
  31. console.log('arr', arr)

分析

  • 时间复杂度:

    • 最好:O(nlogn)
    • 最坏:O(nlogn)
    • 平均:O(nlogn)
      • 轮数:O(logn)
      • 每轮遍历:O(n)
  • 空间复杂度:O(n)
    • 临时的数组 n + 递归时压入栈的数据占用的空间 logn
  • 排序方式:Out-place
  • 稳定性:稳定

5. 快速排序

思路

  • 分区:在数据序列中选择一个元素作为基准值,每趟从数据序列的两端开始交替进行,将小于基准值的元素交换到序列前端,将大于基准值的元素交换到序列后端,介于两者之间的位置则成为基准值的最终位置(将基准值与最终位置或其前一位元素交换)。
  • 递归:递归地对基准前后的子数组进行分区

代码

  1. Array.prototype.quickSort = function () {
  2. // end: 包括
  3. const rec = (start, end) => {
  4. if (end <= start) {
  5. return
  6. }
  7. const pivot = this[start]
  8. let i = start + 1
  9. let j = end
  10. while (i < j) {
  11. while (this[i] <= pivot && i < j) {
  12. i++
  13. }
  14. while (this[j] >= pivot && i < j) {
  15. j--
  16. }
  17. // 若i<j,i和j交换
  18. if (i < j) {
  19. let temp = this[i]
  20. this[i] = this[j]
  21. this[j] = temp
  22. }
  23. }
  24. // i == j 的情况
  25. if (this[i] < pivot) {
  26. // i和pivot交换
  27. let temp = this[i]
  28. this[i] = this[start]
  29. this[start] = temp
  30. rec(start, i - 1)
  31. rec(i + 1, end)
  32. } else {
  33. // i-1和pivot交换
  34. let temp = this[i - 1]
  35. this[i - 1] = this[start]
  36. this[start] = temp
  37. rec(start, i - 2)
  38. rec(i, end)
  39. }
  40. }
  41. rec(0, this.length - 1)
  42. }
  43. const arr = [3, 1, 5, 4, 2]
  44. arr.quickSort()
  45. console.log('arr', arr)

分析

  • 时间复杂度:

    • 最好:O(nlog2n)
    • 最坏:O(n2)【每轮选择的基准值都是极端值(最小/最大)】
    • 平均:O(nlog2n)
      • 轮数:O(log2n)
      • 每轮遍历:O(n)
  • 空间复杂度:O(logn)
    1. 递归时压入栈的数据占用的空间 logn
  • 排序方式:In-place
  • 稳定性:不稳定

JavaScript 实现排序算法的更多相关文章

  1. JavaScript版排序算法

    JavaScript版排序算法:冒泡排序.快速排序.插入排序.希尔排序(小数据时,希尔排序会比快排快哦) //排序算法 window.onload = function(){ var array = ...

  2. javascript高级排序算法之快速排序(快排)

    javascript高级排序算法之快速排序(快排)我们之前讨论了javascript基本排序算法 冒泡排序 选择排序 插入排序 简单复习: 冒泡排序: 比较相邻的两个元素,如果前一个比后一个大,则交换 ...

  3. javascript常用排序算法实现

    毕业后,由于工作中很少需要自已去写一些排序,所以那些排序算法都忘得差不多了,不过排序是最基础的算法,还是不能落下啦,于是找了一些资料,然后用Javascript实现了一些常用的算法,具体代码如下: & ...

  4. javascript常用排序算法总结

    算法是程序的灵魂.虽然在前端的开发环境中排序算法不是很经常用到,但常见的排序算法还是应该要掌握的.我在这里从网上整理了一下常见排序算法的javascript实现,方便以后查阅. 归并排序: 1 fun ...

  5. javascript的排序算法

    已经准备秋招一段时间了,因为这个关系也在各种巩固知识,顺便整理一下一些东西.这篇文章就是自己整理了一下各种JS的排序算法,以便自己以后回顾. 冒泡排序 function bubbleSort(arr) ...

  6. JavaScript之排序算法

    一.冒泡排序 原理:1.比较相邻的元素.如果第一个比第二个大,就交换两个数:2.对每一对相邻元素重复做步骤一,从开始第一对到结尾的最后一对,该步骤结束会产生一个最大的数:3.针对所有的数重复以上的步骤 ...

  7. JavaScript随机排序算法1

    1.对数组循环,每一项与随机的某一项位置调换 <ul id="listOne"></ul> <div id="tempOne"&g ...

  8. JavaScript实现排序算法总结

    <script type="text/javascript" src="js/laydate.js" > //插入排序 function inser ...

  9. javascript实现排序算法

    准备好好学习js了,js写的第一个排序 先推荐一个js在线编辑工具,RunJS,还不错. 冒泡排序 var arr = [2,4,1,5,3]; function handle(arr){ for(v ...

随机推荐

  1. root密码忘记了,怎么办?

    root是管理员使用的超级用户,如果密码忘记了,可以使用以下两种方法修改. 方法一: 进入单用户模式下进行密码修改 步骤1:重启系统,在系统进入3秒启动阶段,快速点击键盘上任意键可以取消默认进入系统状 ...

  2. 什么是ZooKeeper?ZooKeeper分布式事务详解

    前言 上一章我们了解了zookeeper到底是什么,这一章重点来看zookeeper当初到底面临什么问题? 而zookeeper又是如何解决这些问题的? 实际上zookeeper主要就是解决分布式环境 ...

  3. 解决 Idea 下 Lombok 无法使用

    解决:    第一步,项目导入 Lombok 依赖 <dependency> <groupId>org.projectlombok</groupId> <ar ...

  4. hive向es推送数据

    第一步:首先要保证网络是通的,很多公司里子网遍布,要和运维和工程侧同事确认好网络是通的,es的地址可以通过curl es地址的方式测试一下. 第二步:下载需要的jar包,必须的是es-hadoop的包 ...

  5. [LeetCode]231. Power of Two判断是不是2\3\4的幂

    /* 用位操作,乘2相当于左移1位,所以2的幂只有最高位是1 所以问题就是判断你是不是只有最高位是1,怎判断呢 这些数-1后形成的数,除了最高位,后边都是1,如果n&n-1就可以判断了 如果是 ...

  6. VNC使用及其常见问题解决方法

    博主之前在博文(https://www.cnblogs.com/kangbazi666/p/14153604.html)中已经介绍了多人VNC的配置方法,下面将简单介绍其使用方法及常见问题的解决方法. ...

  7. linux学习之--虚拟机安装linux【centerOS】

    计划把学习中的软件安装使用记录下来,以下是使用VMware 按照 Linux 使用桥接网络虚拟机和windows中都有不同的ip地址

  8. python-scrapy框架爬取某瓣电视剧信息--异步加载页面

    前期准备,首先要有python环境+scrapy环境+pycharm环境 一.建立爬虫所需的环境,在命令行输入: scrapy startproject doubantv #命名自定义就好 会生成一个 ...

  9. Android ADB原理及常用命令

    Android调试桥(ADB, Android Debug Bridge)是一个Android命令行工具,包含在SDK 平台工具包中,adb可以用于连接Android设备,或者模拟器,实现对设备的控制 ...

  10. TurtleBot3 Waffle (tx2版华夫)(6)

    重要提示:请在配网通信成功后进行操作,配网后再次开机需要重新验证通信: 重要提示:[Remote PC]代表PC端.[TurtelBot]代表树莓派端: 操作步骤如下: 1)[Remote PC] 启 ...