前言:数据结构与算法无论是前端还是后端开发人员,都是一个无法绕开的话题,也是找工作时笔试必考的内容。在学习完JavaScript的基础知识后,开启数据结构与算法的基础内容学习是十分有必要的。本专栏的目的就是记录自己学习数据结构与算法的一些笔记和感想,从基本的时间空间复杂度启航,栈、队列、链表、堆、树、以及图等内容,包括进阶算法中的冒泡算法、插入算法、归并算法、二分搜索、顺序算法等,以及分而治之,动态规划、贪心等算法设计思想。本专栏的更新速度将根据学习进度而定,每次学习完一个数据结构配合力扣上对应的题目进行巩固,因此会有相关的刷题笔记总结。先对数据结构与算法的基础定义进行具体阐述,然后从算法复杂度概念开篇。
数据结构是计算机存储、组织数据的方式。数据结构是指相互之间存在一种或多种特定关系的数据元素的集合。通常情况下,精心选择的数据结构可以带来更高的运行或者存储效率。数据结构往往同高效的检索算法和索引技术有关。
算法(Algorithm)是指解题方案的准确而完整的描述,是一系列解决问题的清晰指令,算法代表着用系统的方法描述解决问题的策略机制。也就是说,能够对一定规范的输入,在有限时间内获得所要求的输出。如果一个算法有缺陷,或不适合于某个问题,执行这个算法将不会解决这个问题。不同的算法可能用不同的时间,空间或效率来完成同样的任务。一个算法的优劣可以用空间复杂度与时间复杂度来衡量。
一、用什么来定量化的表示复杂度呢?
我们一般使用的是大O表示法,用于描述算法的性能和复杂程度。在使用大O表示法时,我们更多的考虑的是CPU所占用的时间。当算法中存在多种量级的时间复杂度时,我们仅关注量级最大的,用其表示该算法的时间复杂度。
O(1),也叫常数时间,算法运算的时间与传入参数多少无关
O(log n),也叫对数时间,这样的算法包括二分查找;
O(n),也叫线性时间,这样的算法包括简单查找;
O(n*log n),对数多项式,这样的算法包括快速排序(一种速度较快的排序算法);
O(n^2),二次,这样的算法包括选择排序(一种速度较慢的排序算法);
O(n!),阶乘,这样的算法包括旅行商问题(一种非常慢的算法)。
二、时间复杂度
算法的时间复杂度表示的是执行时间随着数据规模增大的变化趋势。
2.1 O(1) 常数级
let n=1;
n-=2;
//以上代码每次仅执行一次
2.2 O(log (n))对数级
while(i<n){
alert(i);
i*=2;
}
//当while循环中的2的n次方等于n时,循环退出,可以算得其时间复杂度为log(n);
2.3 O(n) 线性
for(let i=0;i<n;i++){
alert(i);
}
//循环执行的次数取决于传入的参数n的大小,其算法时间复杂度用O(n表示),这也是我们在代码中所常见的一种时间复杂度。
2.4 O(n^2) 平方级
for(let i=0;i<n;i++){
for(let j=0;j<n;j++){
console.log(i,j);
}
}
//嵌套的for循环在代码中也很常见,其算法的时间复杂度为O(n^2);
以上就是我们在代码中可以常见到的算法的复杂度,从上而下时间复杂度升高,执行时间变长。
三、空间复杂度
空间复杂度衡量的是代码执行所耗费内存空间随着数据规模增长的趋势。同样的使用大O表示法。
3.1 O(1)
const n=0;
//简单的声明初始化了一个常量,占用单个的内存空间
3.2 O(n)
const stack=[];
for(let i=0;i<n;i++){
stack.push(i);
}
//n以内的整数依次压入定义的栈内,需要的存储空间为n
3.2 O(n^2)
let arr=[][];
//对二维数组进行遍历赋值,其需要的存储空间为n^2。
算法的空间复杂度和时间复杂度同样的重要,衡量一个好的算法其标准就是时间复杂度和空间复杂应该尽可能的低,但是在时间和空间存在一定冲突的时候,人们往往会选择时间换空间更侧重于降低算法的时间复杂度。
数据结构与算法学习起来往往比较抽象晦涩,掌握正确的学习方法很重要,再次推荐一个可视化的学习数据结构与算法的网站。VisualGo数据结构可视化学习网站https://visualgo.net/zh
四、归纳总结
本篇博客是数据结构与算法的开篇制作,简单的介绍了数据结构与算法的基础概念,以及用大O表示法来衡量算法的时间复杂度和空间复杂度。本篇的内容比较简单,记录的目的只是为了开启本专栏的撰写,以及一些后面的规划安排。
写博客做学习内容总结是需要花费很长时间的,有时甚至比学习新内容花费的时间更长,有时候也在怀疑费时间去做总结还不如去学一点新的东西呢。但细想之下,学完了并不意味着已经掌握了,学完之后要进行必要的总结归纳,借用一句老话就是好记性比如烂笔头,之前学过的很多东西都是因为没有及时的总结而慢慢忘掉,最终和每学差不多,反而导致大量时间的浪费。学习编程无非就是多写多总结,孰能生巧。
慢慢来,比较快。