递归

Mr.Hotsuitor大约 2 分钟算法算法algo递归

递归

1.大问题可以分解为一个个模式相同的小问题, 即有递归公式 2.有递归结束条件,不能陷入死循环 3.深度在当前系统能承受的范围内,递归深度过深会爆栈

优化重复计算问题,用把计算过的值缓存起来

很典型的例子,斐波那契数列

function fibonacci(n) {
  // 递归结束条件
  if (n == 1 || n == 2) return 1;
  if (!this.cacheMap) {
    this.cacheMap = new Map();
  }
  // 读取缓存数据
  if (this.cacheMap.has(n)) return this.cacheMap.get(n);
  // 递归公式
  let result = fibonacci(n - 1) + fibonacci(n - 2);
  this.cacheMap.set(n, result); // 把计算过的数据缓存起来
  return result;
}

排序算法

冒泡,插入,选择 能用插入排序就用插入排序

  • 冒泡排序,两层 for,两两对比,大数交换往后移
  • 插入排序,取第一个作为有序区间,待排序的数据在无序区间, 从无序区间取数,与有序区间的数比较,插入到合适的位置
  • 选择排序,每次选最小的数,依次排列
排序算法是否原地排序是否稳定排序算法复杂度(最好,最坏,平均)
冒泡O(n),O(n2),O(n2)
插入O(n),O(n2),O(n2)
选择O(n2),O(n2),O(n^2)

稳定性表示,相同数据,是否改变了数据原有的位置,比如 2,4,5,5,1 第一个 5 和第二个 5 的位置没有交换

冒泡排序

function bubbleSort(arr) {
  if (arr.length < 2) return arr;
  for (let i = 0; i < arr.length; i++) {
    for (let j = i + 1; j < arr.length; j++) {
      if (arr[i] > arr[j]) {
        let tmp = arr[j];
        arr[j] = arr[i];
        arr[i] = tmp;
      }
    }
  }
  return arr;
}
bubbleSort([2, 4, 5, 3, 1]); // 1,2,3,4,5

插入排序

function insertionSort(arr) {
  if (arr.length < 2) return arr;
  for (let i = 1; i < arr.length; i++) {
    let tmp = arr[i];
    let j = i - 1;
    for (; j >= 0; j--) {
      if (arr[j] > tmp) {
        arr[j + 1] = arr[j];
      } else {
        break;
      }
    }
    arr[j + 1] = tmp;
  }
  return arr;
}
let arr1 = [2, 5, 3, 6, 1];
console.log(`排序前:${arr1}\n排序后:${insertionSort(arr1)}`);
// 排序前:2,5,3,6,1
// 排序后:1,2,3,5,6

选择排序

function selectSort(arr) {
  if (arr.length < 2) return arr;
  for (let i = 0, len = arr.length; i < len; i++) {
    let k = i; //用于存放当前循环中最小值得index 默认为循环初识值的index
    for (let j = i + 1; j < len; j++) {
      if (arr[j] < arr[k]) {
        k = j;
      }
    }
    if (k !== i) {
      //将最小值与当前循环的第一个值互换位置
      let tmp = arr[k];
      arr[k] = arr[i];
      arr[i] = tmp;
    }
  }
  return arr;
}

let arr1 = [2, 5, 3, 6, 1];
console.log(`排序前:${arr1}\n排序后:${selectSort(arr1)}`);