派大星

vuePress-theme-reco 派大星    2021 - 2022
派大星 派大星
主页
博客
  • 前端
  • JavaScript文章
  • 三级目录
  • 笔记
  • 学习笔记
  • 页面
  • CSS
  • HTML
  • 技术
  • 技术文档
  • GitHub技巧
  • 技术笔记
  • 实用工具
  • Nodejs
  • 博客搭建
  • 更多
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • JavaScript
  • 浏览器&网络
  • 前端框架
  • 资源工具
  • 持续集成
  • 小程序
  • 杂谈
  • React
  • Mysql
  • 面试题
  • uniapp
  • 《ES6 教程》笔记
  • 《Git》学习笔记
  • 《JavaScript教程》笔记
  • 《React》笔记
  • 核心概念
  • 高级指引
  • Hook
  • 案例演示
  • 《TypeScript 从零实现 axios》
  • 初识 TypeScript
  • TypeScript 常用语法
  • ts-axios 项目初始化
  • ts-axios 基础功能实现
  • ts-axios 异常情况处理
  • ts-axios 接口扩展
  • ts-axios 拦截器实现
  • ts-axios 配置化实现
  • ts-axios 取消功能实现
  • ts-axios 更多功能实现
  • ts-axios 单元测试
  • ts-axios 部署与发布
  • 《Vue》笔记
  • 基础
  • 组件
  • 过渡&动画
  • 工具
  • 规模化
  • 可复用性&组合
  • 其他
  • Vuex
标签
时间轴
关于
author-avatar

派大星

272

文章

69

标签

主页
博客
  • 前端
  • JavaScript文章
  • 三级目录
  • 笔记
  • 学习笔记
  • 页面
  • CSS
  • HTML
  • 技术
  • 技术文档
  • GitHub技巧
  • 技术笔记
  • 实用工具
  • Nodejs
  • 博客搭建
  • 更多
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • JavaScript
  • 浏览器&网络
  • 前端框架
  • 资源工具
  • 持续集成
  • 小程序
  • 杂谈
  • React
  • Mysql
  • 面试题
  • uniapp
  • 《ES6 教程》笔记
  • 《Git》学习笔记
  • 《JavaScript教程》笔记
  • 《React》笔记
  • 核心概念
  • 高级指引
  • Hook
  • 案例演示
  • 《TypeScript 从零实现 axios》
  • 初识 TypeScript
  • TypeScript 常用语法
  • ts-axios 项目初始化
  • ts-axios 基础功能实现
  • ts-axios 异常情况处理
  • ts-axios 接口扩展
  • ts-axios 拦截器实现
  • ts-axios 配置化实现
  • ts-axios 取消功能实现
  • ts-axios 更多功能实现
  • ts-axios 单元测试
  • ts-axios 部署与发布
  • 《Vue》笔记
  • 基础
  • 组件
  • 过渡&动画
  • 工具
  • 规模化
  • 可复用性&组合
  • 其他
  • Vuex
标签
时间轴
关于

【数据结构与算法图解】- 算法基础

vuePress-theme-reco 派大星    2021 - 2022

【数据结构与算法图解】- 算法基础

派大星 2021-01-14 算法

个人感觉 【数据结构与算法图解】这本书讲的比较简单,有计算机基础的不推荐看

# 尽量减少重复劳动力

系统学习推荐小伙伴直接去 awesome-coding-js (opens new window)

这里是我个人学习的的一些小结

# 【数据结构与算法图解】 结合 awesome-coding-js 总结的

个人感觉 【数据结构与算法图解】这本书讲的比较简单,有计算机基础的不推荐看

# 1、一些概念

  • 时间复杂度 理论:操作的速度,并不按时间计算,而是按步数 计算
  • 读取:一步,查找:最多N步,插入:最多N+1(N次移动,1次插入),删除:最多N

# 2、查找

  • 线性查找: 一个个查,比对
  • 二分查找: 每次有序数组长度乘以 2,二分查找所需的最多步数只会加 1。

# 3、大 O 记法

一般指: 最坏的情况

  • O(1) 不管需要多少步,步数不变就是O(1)
  • O(N) 根据数据量变化而变化
  • O(log N) 对数时间,比如二分查找,数据量翻倍时,步数+1

JavaScript简单记(不准):根据for循环的数量来记,2个for就是O(n2)

# 4、冒泡排序

# 概念

循环数组,比较当前元素和下一个元素,如果当前元素比下一个元素大,向上冒泡。

这样一次循环之后最后一个数就是本数组最大的数。

下一次循环继续上面的操作,不循环已经排序好的数。

优化:当一次循环没有发生冒泡,说明已经排序完成,停止循环

# 解法

function bubbleSort(array) {
      for (let j = 0; j < array.length; j++) {
        let complete = true;
        for (let i = 0; i < array.length - 1 - j; i++) {
          // 比较相邻数
          if (array[i] > array[i + 1]) {
            [array[i], array[i + 1]] = [array[i + 1], array[i]];
            complete = false;
          }
        }
        // 没有冒泡结束循环
        if (complete) {
          break;
        }
      }
      return array;
    }

# 复杂度

时间复杂度:O(n2)

空间复杂度:O(1)

# 5、选择排序

每次循环选取一个最小的数字放到前面的有序序列中。

# 解法

 function selectionSort(array) {
      for (let i = 0; i < array.length - 1; i++) {
        let minIndex = i;
        for (let j = i + 1; j < array.length; j++) {
          if (array[j] < array[minIndex]) {
            minIndex = j;
          }
        }
        [array[minIndex], array[i]] = [array[i], array[minIndex]];
      }
    }

# 复杂度

时间复杂度:O(n2)

空间复杂度:O(1)

# 大O记法忽略常数

选择排序的步数大概只有冒泡排序的一半,即选择排序比冒泡排序 快一倍。

但是严格来说选择排序应为 O(N2 / 2),最终得写成 O(N2 )。

类似地,O(2N)要写成 O(N); O(N / 2)也写成 O(N);就算是比 O(N)慢 100 倍的 O(100N),也要写成 O(N)。

# 6、插入排序

将左侧序列看成一个有序序列,每次将一个数字插入该有序序列。

插入时,从有序序列最右侧开始比较,若比较的数较大,后移一位。

function insertSort(array) {
      for (let i = 1; i < array.length; i++) {
        let target = i;
        for (let j = i - 1; j >= 0; j--) {
          if (array[target] < array[j]) {
            [array[target], array[j]] = [array[j], array[target]]
            target = j;
          } else {
            break;
          }
        }
      }
      return array;
    }

# 复杂度

时间复杂度:O(n2)

空间复杂度:O(1)

# 7、快速排序

快速排序:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据比另一部分的所有数据要小,再按这种方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,使整个数据变成有序序列。

先从右往左找一个小于 基准值 的数,再从左往右找一个大于 基准值 的数,然后交换他们。

这个图解很清楚:算法 3:最常用的排序——快速排序 (opens new window)

实现步骤:

  • 选择一个基准元素target(一般选择第一个数)
  • 将比target小的元素移动到数组左边,比target大的元素移动到数组右边
  • 分别对target左侧和右侧的元素进行快速排序

简单版本

function quickSort(array) {
      if (array.length < 2) {
        return array;
      }
      const target = array[0];
      const left = [];
      const right = [];
      for (let i = 1; i < array.length; i++) {
        if (array[i] < target) {
          left.push(array[i]);
        } else {
          right.push(array[i]);
        }
      }
      return quickSort(left).concat([target], quickSort(right));
    }

# 8、数据结构

  • 链表(带有存储下一个结点地址的)插入和删除效率比数组高很多

# 9、空间复杂度

空间复杂度:当所处理的数据有 N 个元素时,该算法还需额外消耗多少元素大小的内存空间

O(1): 记住,时间 复杂度的O(1)意味着一个算法无论处理多少数据,其速度恒定。相似地,空间复杂度的 O(1)则 意味着一个算法无论处理多少数据,其消耗的内存恒定。