前言
大学里的基础课程例如操作系统,计算机网络,通信原理,硬件基础和数据结构等作为技术人员的内功,是每个从事IT行业的优质程序员必备的基础知识。只有拥有扎实的基础知识,才能在这个瞬息万变的年代中,以不变应万变,掌握主动性。今天是2018年12月15日周六,庆幸自己意识到的还不至于太晚,接下来这段时间,我会将自己算法的学习笔记整理在博客上,每周至少更新三篇左右,请各位监督。
数据结构和算法是什么?
广义来说,数据结构就是一组数据的存储结构,算法就是一组数据的操作方法。两者相辅相成,数据结构是为算法服务,算法是作用于某个特定的数据结构,脱离了数据结构的算法好似空中楼阁,脱离算法孤立存在的数据结构没有存在的意义。
数据结构和算法要解决什么问题?
数据结构和算法解决的是如何更省、更快的存储和处理数据的问题。因此,为了能更直观的考量效率和资源消耗,提出了一个复杂度分析方法,复杂度分析方法是算法的精髓。
最常见的数据结构和算法
数据结构
数组,链表,栈,队列,散列表,二叉树,堆,跳表,图,Trie树;
算法
递归,排序,二分查找,搜索,哈希算法,贪心算法,分治算法,回溯算法,动态规划,字符串匹配算法
复杂度分析方法
进行复杂度分析的原因
- 平时使用的通过运行代码后得出的时间和空间分析方法测试结果非常依赖测试环境,i9和i3处理器处理时间肯定不一致。
- 测试结果受数据规模的影响很大,测试数据规模太小,测试结果无法真实反应算法的性能
大O复杂度表示法
一个不需要具体的测试数据来测试,就可以粗略估计算法执行效率的方法。算法执行效率粗略的讲就是算法代码执行的时间,但是如何在不运行代码的情况下用“肉眼”得到一段代码的运行时间呢?这是一段从1到n累加和的代码:
int test(int n){
int sum=0;
for(int i=1;i<=n;i++){
sum=sum+i;
}
return sum;
}
从cpu角度来说,假设每一行代码的操作读数据-写数据-运算执行时间相等(实际这三种操作执行时间并不相同)。但我们估计来说,假设他们每执行一次操作需要一个time的时间,从上面的代码来说,总共执行了2次写操作,2n次运算,即执行的时间为:
( 2 n + 2 ) ∗ t i m e (2n+2)*time (2n+2)∗time
所以在这个代码中,T(n)=O(2n+2)。把这个规律总结成一个公式,即:
T ( n ) = O ( f ( n ) ) T(n)=O(f(n)) T(n)=O(f(n))
其中,T(n)是代码执行的时间;n表示数据规模的大小;f(n)表示所有代码执行的次数总和。公式中的O表示T(n)和f(n)成正比。这就是大O时间复杂度表示法。当n的取值非常大时,公式中的低阶常量系数并不能对增长趋势造成很大影响,所以忽略后,我们只需要记录一个最大量级就可以了。所以,第一个代码的时间复杂度变成了我们最熟悉的一个式子:
T ( n ) = O ( n ) T(n)=O(n) T(n)=O(n)
时间复杂度分析
只关注循环执行次数最多的一段代码
大O复杂度表示法中说了要忽略掉公式中的常量系数低阶等,所以时间复杂度分析只关注循环执行次数最多的代码。
加法法则
总的时间复杂度等于量级最大的代码的时间复杂度。即:
T 1 ( n ) = O ( f ( n ) ) ; T 2 (