前端排序算法

一、冒泡排序

双层循环 内层循环两两比较换位,直到当前轮次的最大的数被交换至末尾

GIF图

代码

javascript 复制代码
// 冒泡排序
const sort = (arr) => {
  for (let i = 0; i < arr.length - 1; i++) {
    let swap = false;
    for (let j = 0; j < arr.length - 1 - i; j++) {
      if (arr[j] > arr[j + 1]) {
        [arr[j], arr[j + 1]] = [arr[j + 1], arr[j]];
        swap = true;
      }
    }
    if (!swap) {
      break;
    }
  }
  return arr
};

// 测试
const arr = [5, 3, 8, 4, 2];
console.log(sort(arr)); // [2, 3, 4, 5, 8]

二、选择排序

将数组分为 "已排序区" 和 "未排序区",每轮从未排序区找到最小元素,放到已排序区末尾

GIF图

代码

javascript 复制代码
// 选择排序(优化版)
const sort = (arr) => {
  // 最后一个元素不需要再找最小值,因为前面都已经排序好了
  for (let i = 0; i < arr.length - 1; i++) {
    let tempIndex = i;
    for (let j = i + 1; j < arr.length; j++) {
      if (arr[j] < arr[tempIndex]) {
        tempIndex = j;
      }
    }
    // 避免不必要的交换
    if (tempIndex !== i) {
      [arr[i], arr[tempIndex]] = [arr[tempIndex], arr[i]];
    }
  }
  return arr;
};

// 测试
const arr = [5, 3, 8, 4, 2];
console.log(sort(arr)); // [2, 3, 4, 5, 8]

三、插入排序

将数组分为 "已排序区" 和 "未排序区",逐个取未排序区元素,插入到已排序区的正确位置

GIF图

代码

javascript 复制代码
// 插入排序
const sort = (arr) => {
  
  for (let i = 1; i < arr.length; i++) {
    // 保存当前要插入的元素
    const currentItem = arr[i]; 
    let j = i - 1; 
    
    // 将比 currentItem 大的元素向后移动
    while (j >= 0 && arr[j] > currentItem) {
      arr[j + 1] = arr[j];
      j--;
    }
    
    // 将 currentItem 插入到正确位置
    arr[j + 1] = currentItem;
  }
  
  return arr;
};

// 测试
const arr = [5, 3, 8, 4, 2];
console.log(sort(arr)); // [2, 3, 4, 5, 8]

四、快速排序

分治思想 ------ 选一个 "基准值",将数组分为 "小于基准""等于基准""大于基准" 三部分,递归排序左右两部分

GIF图

代码

javascript 复制代码
// 快速排序
const sort = (arr) => {
  if (arr.length <= 1) {
    return arr;
  }
  const sign = arr[Math.floor(arr.length / 2)];
  const left = [];
  const center = [];
  const right = [];
  for (let i = 0; i < arr.length; i++) {
    if (arr[i] < sign) {
      left.push(arr[i]);
    } else if (arr[i] === sign) {
      center.push(arr[i]);
    } else {
      right.push(arr[i]);
    }
  }

  return [...sort(left), ...center, ...sort(right)];
};

// 测试
const arr = [5, 3, 8, 4, 2];
console.log(sort(arr)); // [2, 3, 4, 5, 8]

五、归并排序

分治思想 ------ 先把数组拆分成最小单元(单个元素),再两两合并成有序数组,最终合并为完整有序数组

GIF图

代码

javascript 复制代码
// 归并排序
const sort = (arr) => {
  if (arr.length <= 1) {
    return [...arr];
  }
  const middle = Math.floor(arr.length / 2);
  const left = sort(arr.slice(0, middle));
  const right = sort(arr.slice(middle));

  const merge = (_left, _right) => {
    
    const arr = [];
    let i = 0;
    let j = 0;
    while (i < _left.length && j < _right.length) {
      if (_left[i] < _right[j]) {
        arr.push(_left[i++]);
      } else {
        arr.push(_right[j++]);
      }
    }
    return [...arr, ..._left.slice(i), ..._right.slice(j)];
  };
  return merge(left, right);
};

// 测试
const arr = [5, 3, 8, 4, 2];
console.log(sort(arr)); // [2, 3, 4, 5, 8]

六、手写Array.prototype.sort()

使用快速排序手写一个sort方法

GIF图

代码

javascript 复制代码
// 手写Array.prototype.sort()
const sort = (arr, fn) => {
  if (arr.length <= 1) {
    return [...arr];
  }

  function defaultFn(a, b) {
    const _a = String(a);
    const _b = String(b);
    if (_a < _b) return -1;
    if (_a > _b) return 1;
    return 0;
  }
  const compareFn = fn ? fn : defaultFn;

  const left = [];
  const center = [];
  const right = [];
  const sign = arr[Math.floor(arr.length / 2)];

  for (let i = 0; i < arr.length; i++) {
    if (compareFn(arr[i], sign) < 0) {
      left.push(arr[i]);
    } else if (compareFn(arr[i], sign) > 0) {
      right.push(arr[i]);
    } else {
      center.push(arr[i]);
    }
  }
  return [...sort(left, compareFn), ...center, ...sort(right, compareFn)];
};

// 测试
const arr = [5, 3, 8, 4, 2];
console.log(sort(arr)); // [2, 3, 4, 5, 8]
相关推荐
2401_831824962 小时前
基于C++的区块链实现
开发语言·c++·算法
We་ct2 小时前
LeetCode 918. 环形子数组的最大和:两种解法详解
前端·数据结构·算法·leetcode·typescript·动态规划·取反
愣头不青2 小时前
238.除了自身以外数组的乘积
数据结构·算法
人工智能AI酱2 小时前
【AI深究】逻辑回归(Logistic Regression)全网最详细全流程详解与案例(附大量Python代码演示)| 数学原理、案例流程、代码演示及结果解读 | 决策边界、正则化、优缺点及工程建议
人工智能·python·算法·机器学习·ai·逻辑回归·正则化
WangLanguager2 小时前
逻辑回归(Logistic Regression)的详细介绍及Python代码示例
python·算法·逻辑回归
m0_518019482 小时前
C++与机器学习框架
开发语言·c++·算法
一段佳话^cyx2 小时前
详解逻辑回归(Logistic Regression):原理、推导、实现与实战
大数据·算法·机器学习·逻辑回归
qq_417695052 小时前
C++中的代理模式高级应用
开发语言·c++·算法
xiaoye-duck3 小时前
《算法题讲解指南:动态规划算法--路径问题》--5.不同路径,6.不同路径II
c++·算法·动态规划
ambition202423 小时前
最大子数组和算法全解析:从暴力枚举到动态规划优化
数据结构·c++·算法