当前位置: 首页 > ai >正文

JavaScript常用的算法详解

1. 排序算法

1.1. 冒泡排序(Bubble Sort)

冒泡排序是一种简单的排序算法,通过反复遍历数组,将相邻的两个元素进行比较并交换位置,从而将最大的元素逐步移到数组的末尾。

优点:

  • 实现简单:算法逻辑简单,易于理解。

  • 原地排序:不需要额外的内存空间,空间复杂度为 O(1)。

缺点:

  • 效率低下:时间复杂度为 O(n²),对大规模数据排序效率很差。

  • 适合小规模数据:对于小规模数据或几乎有序的数据有一定效果。

代码示例:

function bubbleSort(arr: number[]): number[] {const len = arr.length;for (let i = 0; i < len; i++) {for (let j = 0; j < len - i - 1; j++) {if (arr[j] > arr[j + 1]) {[arr[j], arr[j + 1]] = [arr[j + 1], arr[j]]; // 交换位置}}}return arr;
}

使用场景:

  • 小规模数据排序:当数据量很小时可以使用,尤其是数据几乎有序时。

1.2. 选择排序(Selection Sort)

选择排序每次从未排序的部分选择最小或最大的元素,放到已排序部分的末尾,逐步缩小未排序部分。

优点:

  • 简单直观:逻辑简单,易于实现。

  • 数据移动次数少:每次交换只涉及一次最小值移动。

缺点:

  • 效率较低:时间复杂度为 O(n²),大规模数据表现不佳。

  • 不稳定排序:相同元素的相对顺序可能会被改变。

代码示例:

function selectionSort(arr: number[]): number[] {const len = arr.length;for (let i = 0; i < len - 1; i++) {let minIndex = i;for (let j = i + 1; j < len; j++) {if (arr[j] < arr[minIndex]) {minIndex = j;}}if (minIndex !== i) {[arr[i], arr[minIndex]] = [arr[minIndex], arr[i]]; // 交换最小值到已排序部分}}return arr;
}

使用场景:

  • 小规模数据排序:适合数据量较少的情况。

  • 对内存写操作敏感的场景:如硬盘排序或闪存存储。

1.3. 插入排序(Insertion Sort)

插入排序通过将每个元素插入到已排序部分的适当位置,逐步构建有序序列。

优点:

  • 适合小规模数据:表现较好,尤其是数据接近有序时。

  • 稳定排序:相同元素的相对顺序不会改变。

缺点:

  • 效率较低:时间复杂度为 O(n²),无序数据时性能较差。

代码示例:

function insertionSort(arr: number[]): number[] {const len = arr.length;for (let i = 1; i < len; i++) {let key = arr[i];let j = i - 1;while (j >= 0 && arr[j] > key) {arr[j + 1] = arr[j]; // 将比 key 大的元素后移j--;}arr[j + 1] = key;}return arr;
}

使用场景:

  • 小规模数据排序:适合数据量较少的情况。

  • 几乎有序的数据:当数据接近有序时,插入排序的时间复杂度接近 O(n)。

1.4. 归并排序(Merge Sort)

归并排序是一种基于分治思想的排序算法,将数组分为两个子数组,递归排序后合并成一个有序数组。

优点:

  • 时间复杂度稳定:O(n log n),适合大规模数据。

  • 稳定排序:相同元素的相对顺序不变。

缺点:

  • 需要额外空间:需要 O(n) 的额外空间存储合并结果。

代码示例:

function mergeSort(arr: number[]): number[] {if (arr.length <= 1) return arr;const mid = Math.floor(arr.length / 2);const left = mergeSort(arr.slice(0, mid));const right = mergeSort(arr.slice(mid));return merge(left, right);
}function merge(left: number[], right: number[]): number[] {const result: number[] = [];let i = 0, j = 0;while (i < left.length && j < right.length) {if (left[i] < right[j]) {result.push(left[i]);i++;} else {result.push(right[j]);j++;}}return result.concat(left.slice(i), right.slice(j));
}

使用场景:

  • 大规模数据排序:归并排序适合处理大量数据。

  • 链表排序:归并排序在链表上的效率高于其他排序算法。

1.5. 快速排序(Quick Sort)

快速排序通过选择一个基准元素,将数组分为小于和大于基准的两部分,递归排序。

优点:

  • 平均性能优异:时间复杂度为 O(n log n),常数因子小,适合大规模数据。

  • 原地排序:不需要额外的存储空间,空间复杂度为 O(log n))。

缺点:

  • 最坏情况退化:在不好的情况下,时间复杂度会退化为 O(n²)。

  • 不稳定排序:相同元素的相对顺序可能改变。

代码示例:

function quickSort(arr: number[]): number[] {if (arr.length <= 1) return arr;const pivot = arr[Math.floor(arr.length / 2)];const left = arr.filter(x => x < pivot);const right = arr.filter(x => x > pivot);const middle = arr.filter(x => x === pivot);return quickSort(left).concat(middle, quickSort(right));
}

使用场景:

  • 大规模数据排序:快速排序是实际应用中常用的排序算法之一。

  • 对空间要求敏感的场景:快速排序为原地排序。

1.6. 希尔排序(Shell Sort)

希尔排序是插入排序的改进版,通过将数组按照一定的间隔分为多个子序列,先对每个子序列进行插入排序,然后逐渐减小间隔直到最后对整个序列进行插入排序。

优点:

  • 改进了插入排序:通过间隔分组,减少了大数据量的移动,提升了效率。

  • 适合中等规模数据

http://www.xdnf.cn/news/18777.html

相关文章:

  • 8.26网络编程——Modbus TCP
  • 【跨国数仓迁移最佳实践7】基于MaxCompute多租的大数据平台架构
  • 发力低空经济领域,移动云为前沿产业加速崛起注入云端动能
  • Tomcat下载历史版本
  • 前沿技术趋势与应用:探索数字世界的下一个十年
  • 【第三章】软件测试缺陷管理:从判断到回归的全流程实践指南​
  • 支持向量机学习
  • 33.ansible 比较重要的配置文件
  • 可口可乐考虑出售Costa咖世家!加上星巴克中国、Peet’s皮爷咖啡,三大国际咖啡品牌“纷纷卖身”!咖啡行业格局彻底改写!
  • MyBatis-Flex是如何避免不同数据库语法差异的?
  • 微服务-23.网关登录校验-自定义GlobalFilter
  • 数据结构青铜到王者第五话---LinkedList与链表(2)
  • 洛谷: CF632D Longest Subsequence-普及+/提高
  • 相机激光安全等级和人眼安全
  • 亚马逊云科技免费套餐新政解析与实战:数据分析与可视化平台
  • 机器学习(二)特征工程
  • 深度剖析初始化vue项目文件结构!!【前端】
  • (MySQL索引事务) 本节目标 索引 事务
  • 机器学习--支持向量机
  • 数据结构(一):算法的时间复杂度和空间复杂度
  • 在使用spring ai进行llm处理的rag的时候,选择milvus还是neo4j呢?
  • 固定资产管理系统核心模块拆解:全流程管理逻辑
  • 30.LSTM-长短时记忆单元
  • 视频号存在争议了...
  • 从零开始的 Docker 之旅
  • 嵌入式系统学习Day23(进程)
  • 今日分享:C++ string 类模拟实现
  • 【Linux系统】线程概念
  • 【51单片机】萌新持续学习中《矩阵 密码锁 点阵屏》
  • 抽象能力的重要性