持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第4天,点击查看活动详情
简介
数据结构(Data Structure):计算机存储、组织数据的方式。
算法(Algorithm):一系列解决问题的指令。算法研究的目的是为了更有效的处理数据,提高数据运算效率。
数据结构与算法的关系:
- 程序 = 数据结构 + 算法
- 数据结构为算法提供服务,算法围绕数据结构操作
算法为一些特定的数据结构提供了解决方案,如下表:
数据结构 | 算法 |
---|---|
链表 | 遍历链表、删除链表节点 |
树、图 | 深度/广度优先遍历 |
数组 | 冒泡/选择/插入/归并/快速排序、顺序/二分搜索 |
如何学习数据结构与算法
要想学好数据结构与算法可以从下面几个点入手:
- 理论:熟悉数据结构与算法的特点,应用场景
- 刷题:做一些算法题
- 实战:在工作、真实项目中使用
理论
了解掌握常见的数据结构,如下:
- 栈:
先进后出(FILO)
的数据结构,是一种特殊的线性表 - 队列:
先进先出(FIFO)
的数据结构,是一种特殊的线性表 - 链表:数据元素按照链式存储结构进行存储的数据结构
- 集合:由一组
无序且不重复
的元素构成(ES6中的Set
) - 字典:无序的、由
键-值(key-value)
对组成的集合(ES6中的Map
) - 树:由n(n≥0)个有限节点组成一个具有层次关系的集合,非线性结构
- 图:由若干给定的顶点及连接两顶点的边所构成的图形
- 堆:一种经过排序的树形数据结构,每个节点都有一个值,通常我们所说的堆的数据结构是指二叉树
了解掌握常见的排序与搜索算法:冒泡算法、选择算法、插入算法、归并算法、快速算法、顺序算法、二分搜索等
了解掌握常见的算法设计思想:分而治之、动态规划、贪心算法、回溯算法
刷题
LeetCode
刷题推荐分类型刷题,不推荐按题号刷。- 重点关注通用套路,分析时间复杂度与空间复杂度,如何优化时间复杂度与空间复杂度。
实战
- 前端与数据结构/算法的结合点(JS中的堆栈、任务队列等)
- 可以通过阅读vue、react等前端流行库的源码来了解数据结构与算法在前端的应用
- 工作中使用
算法复杂度
算法复杂度是指算法在编写成可执行程序后,运行时所需要的资源,资源包括时间资源和内存资源。
进一步分为 时间复杂度 和 空间复杂度。
时间复杂度
时间复杂度 是一个函数,描述该算法的运行时间(大概的时间或趋势,不代表具体的多少秒)。表示方式:用大写字母 O
表示,比如:O(1)
O(n)
O(logN)
等。
用JS代码来理解:
- 如下是
O(1)
时间复杂度的代码,只会执行一次:
let i = 0
i += 1
- 如下是
O(n)
时间复杂度的代码,for循环
内代码会执行n次:
for(let j = 0; j < n; j++) {
console.log(j)
}
将前面两段代码结合,时间复杂度也是O(n)
,可以理解为 O(1) + O(n) = O(n)
let i = 0
i += 1
for(let j = 0; j < n; j++) {
console.log(j)
}
- 如下是
O(n^2)
【O(n)的二次方】时间复杂度的代码,双层for循环
:
for(let j = 0; j < n; j++) {
for(let i = 0; i < n; i++) {
console.log(j, i)
}
}
- 如下是
O(logN)
时间复杂度的代码,while循环体
内的代码执行了logN
次:
let i = 1
while(i < n) {
console.log(i)
i *= 2
}
while
停止执行的时机是当 i >= n
的时候,也就是求 2的多少次方大于等于n
,所以这个次数是 logN
次。
空间复杂度
空间复杂度 是一个函数,表示算法运行过程中临时占用的空间的大小。表示方式:用大写字母 O
表示,比如:O(1)
O(n)
O(n^2)
等。
用JS代码来理解:
- 如下是
O(1)
时间复杂度的代码,单个变量占用空间:
let i = 0
i += 1
- 如下是
O(n)
时间复杂度的代码,数组内添加进了n个值相当于占用了n个内存单元:
const arr = []
for(let j = 0; j < n; j++) {
arr.push(j)
}
- 如下是
O(n^2)
时间复杂度的代码,arr
是二位数组/矩阵,占用了n的二次方个内存单元
:
const arr = []
for(let j = 0; j < n; j++) {
arr.push([])
for(let i = 0; i < n; i++) {
arr[j].push(i)
}
}