数据结构与算法之美
数据结构与算法之美
数据结构与算法之美
程序猿DD啊 昨天
数据结构和算法是程序员的内功心法和基本功。无论是人工智能还是其它计算机科学领域,掌握扎实的数据结构和算法知识,往往会助力不少!
算法是计算机处理信息的本质,因为计算机程序本质上是一个算法来告诉计算机确切的步骤来执行一个指定的任务。一般地,当算法在处理信息时,会从输入设备或数据的存储地址读取数据,把结果写入输出设备或某个存储地址供以后再调用。
算法是独立存在的一种解决问题的方法和思想。
对于算法而言,实现的语言并不重要,重要的是思想。
算法可以有不同的语言描述实现版本(如C描述、C++描述、Python描述等),我们现在是在用Python语言进行描述实现。
算法的五大特性
- 输入: 算法具有0个或多个输入
- 输出: 算法至少有1个或多个输出
- 有穷性: 算法在有限的步骤之后会自动结束而不会无限循环,并且每一个步骤可以在可接受的时间内完成
- 确定性:算法中的每一步都有确定的含义,不会出现二义性
- 可行性:算法的每一步都是可行的,也就是说每一步都能够执行有限的次数完成
数据结构是以某种形式将数据组织在一起的集合,它不仅存储数据,还支持访问和处理数据的操作。算法是为求解一个问题需要遵循的、被清楚指定的简单指令的集合。
下图是算法和数据结构相关知识的总览
当然我们并不需要全部掌握它们,王争老师列举了常用20个用法。10个数据结构:
数组、链表、栈、队列、散列表、二叉树、堆、跳表、图、Trie树
;10个算法:
递归、排序、二分查找、搜索、哈希算法、贪心算法、分治算法、回溯算法、动态规划、字符串匹配算法
。
时间复杂度和空间复杂度分析
数据结构和算法本身就是为了解决“快”和“省”的问题。让代码运行更快,更省储存空间。那首先我们就要先了解自己写的代码复杂度,这里就需要用到时间复杂度和空间复杂度分析。
1.大O复杂度表示法
算法的执行效率,粗略地讲就是算法的执行时间。下面的代码是求1,2,3…n累加的和。
int cal(int n) {
int sum = 0;
int i = 1;
for (; i <= n; ++i) {
sum += i;
}
return sum;
}
从CPU的角度,这段代码的操作是,
读数据 -> 运算 -> 写数据
,如果每一个操作都是unit_time,第二行和第三行是一个unit_time,而第四行和第五行的for循环是2n个unit_time,加上return操作。时间复杂度就是2n+3,一般计算的时候会把常量省略,所以这个程序的时间复杂度就是n。所以就可以推断出,所以代码的执行时间T(n)与每行代码的的执行次数成正比。
引出重要概念,所有代码的执行时间 T(n) 与每行代码的执行次数 n 成正。
T(n) = O(f(n))
2.复杂度分析法则
- 单段代码,看高频,循环的次数。
- 多段代码取最大,如果一段代码里单次循环和多重循环,忽略单词,取多重。
- 嵌套代码求乘积,比如递归和多重循环。
- 多个规模求加法,比如方法有两个参数控制两个循环的次数,这时候,就需要取两者复杂度相加。
3.常用的复杂度级别
多项式阶:随着数据规模的增长,算法的执行时间和空间占用,按照多项式的比例增长,包括,O(1)(常数阶)、O(logn)(对数阶)、O(n)(线性阶)、O(nlogn)(线性对数阶)、O(n^2)(平方阶)、O(n^3)(立方阶)。
非多项式阶:随着数据规模的增长,算法的执行时间和空间占用暴增,这列算法性能极差。包括,O(2^n)(指数阶)、O(n!)(阶乘阶)
复杂度分析的四个概念
- 最坏情况时间复杂度:代码在最坏情况下执行的时间复杂度。
- 最好情况时间复杂度:代码在最理想情况下执行的时间复杂度。
- 平均时间复杂度:用代码在所有情况下执行的次数的加权平均值表示。
- 均摊时间复杂度:在代码执行的所有复杂度情况中绝大部分是低级别的复杂度,个别情况是高级别复杂度且发生具有时序关系时,可以将个别高级别复杂度均摊到低级别复杂度上。基本上均摊结果就等于低级别复杂度。
区分平均时间复杂度和均摊时间复杂度
1.平均时间复杂度
代码在不同情况下复杂度出现量级差别,则用代码所有可能情况下执行次数的加权平均值表示。
2.均摊时间复杂度
两个条件满足时使用:
1)代码在绝大多数情况下是低级别复杂度,只有极少数情况是高级别复杂度;
2)低级别和高级别复杂度出现具有时序规律。均摊结果一般都等于低级别复杂度。
扫 码 关 注