- 复杂度分析是整个算法学习的精髓,只要掌握了它,数据结构和算法的内容基本上就掌握了一半。
大 O 时间复杂度表示法,表示代码执行时间随数据规模增长的变化趋势。所以也叫做渐进事件复杂度,简称时间复杂度。
时间复杂度分析:
- 只关注循环执行次数最多的一段代码。
- 加法法则:总复杂度等于量级最大的那段代码的复杂度。
- 乘法法则:嵌套代码的复杂度等于嵌套内外代码复杂度的乘积。
如果 T1(n)=O(f(n)),T2(n)=O(g(n));那么 T(n)=T1(n)T2(n)=O(f(n))O(g(n))=O(f(n)*g(n)).
即便代码循环 10000 次、100000 次,只要是一个已知的数,跟 n 无关,照样也是常量级的执行时间。
复杂度量级:多项式量级、非多项式量级。非多项式时间复杂度的算法是非常低效的算法。
一般情况下,只要算法中不存在循环语句、递归语句,即使有成千上万行的代码,其时间复杂度也是Ο(1)。
空间复杂度:表示算法的存储空间与数据规模之间的增长关系
我们常见的空间复杂度就是 O(1)、O(n)、O(n^2)
复杂度也叫渐进复杂度,包括时间复杂度和空间复杂度,用来分析算法执行效率与数据规模之间的增长关系,可以粗略地表示,越高阶复杂度的算法,执行效率越低。
渐进式时间,空间复杂度分析与性能基准测试并不冲突,而是相辅相成的,但是一个低阶的时间复杂度程序有极大的可能性会优于一个高阶的时间复杂度程序,所以在实际编程中,时刻关心理论时间,空间度模型是有助于产出效率高的程序的,同时,因为渐进式时间,空间复杂度分析只是提供一个粗略的分析模型,因此也不会浪费太多时间,重点在于在编程时,要具有这种复杂度分析的思维。
只有同一块代码在不同的情况下,时间复杂度有量级的差距,我们才会使用最好、最坏、平均情况这三种复杂度表示法来区分。
对一个数据结构进行一组连续操作中,大部分情况下时间复杂度都很低,只有个别情况下时间复杂度比较高,而且这些操作之间存在前后连贯的时序关系,这个时候,我们就可以将这一组操作放在一块儿分析,看是否能将较高时间复杂度那次操作的耗时,平摊到其他那些时间复杂度比较低的操作上。而且,在能够应用均摊时间复杂度分析的场合,一般均摊时间复杂度就等于最好情况时间复杂度。
均摊时间复杂度就是一种特殊的平均时间复杂度。我们没必要花太多精力去区分它们。你最应该掌握的是它的分析方法,摊还分析。至于分析出来的结果是叫平均还是叫均摊,这只是个说法,并不重要。
为什么大部分书都把这两个东西放到一块儿来讲呢?
这是因为,数据结构和算法是相辅相成的。数据结构是为算法服务的,算法要作用在特定的数据结构之上。 因此,我们无法孤立数据结构来讲算法,也无法孤立算法来讲数据结构。
从广义上讲,数据结构就是指一组数据的存储结构。算法就是操作数据的一组方法。
从狭义上讲,也就是我们专栏要讲的,是指某些著名的数据结构和算法,比如队列、栈、堆、二分查找、动态规划等。
数据结构是静态的,它只是组织数据的一种方式。如果不在它的基础上操作、构建算法,孤立存在的数据结构就是没用的。
要学习算法与数据结构的“来历”“自身的特点”“适合解决的问题”以及“实际的应用场景”
学习知识的过程是反复迭代、不断沉淀的过程。
打怪升级,十种数据结构和十种算法