数据结构与算法-总结(二):算法概述
一、算法定义
算法:为了实现业务目的的各种方法和思路就是算法。同样的数据,同样的目的, 不同的算法,不同的方法和思路,效率就会不同
算法是一种独立的存在 , 它并不依附于代码 , 代码只是实现算法思想的方式而已。
算法是独立存在的一种解决问题的方法和思想
对于算法而言,实现的语言并不重要,重要的是思想
算法可以有不同的语言描述实现版本(如C描述、C++描述、Python描述等)
二、算法的五大特性
- 输入: 算法具有0个或多个输入
- 输出: 算法至少有1个或多个输出
- 有穷性: 算法在有限的步骤之后会自动结束而不会无限循环,并且每一个步骤可以在可接受的时间内完成
- 确定性:算法中的每一步都有确定的含义,不会出现二义性
- 可行性:算法的每一步都是可行的,也就是说每一步都能够执行有限的次数完成
三、算法优劣的衡量:时间复杂度、空间复杂度
1. 时间复杂度
1.1 大O表示法
时间复杂度可以表示一个算法随着问题规模不断变化的最主要趋势 , 同时时间复杂度往往和大O表示法一起使用
1.2 时间复杂度的计算规则
- 基本操作,认为其时间复杂度为O(1)
- 顺序结构,时间复杂度按加法进行计算
- 循环结构,时间复杂度按乘法进行计算
- 分支结构,时间复杂度取最大值
- 判断一个算法的效率时,往往只需要关注操作数量的最高次项,其它次要项和常数项可以忽略
- 在没有特殊说明时,我们所分析的算法的时间复杂度都是指最坏时间复杂度
1.3 最优、最坏时间复杂度
分析算法时,存在几种可能的考虑:
- 算法完成工作最少需要多少基本操作,即最优时间复杂度
- 算法完成工作最多需要多少基本操作,即最坏时间复杂度
- 算法完成工作平均需要多少基本操作,即平均时间复杂度
假如我们有一个列表 , 我们要通过一个算法从这个列表中找到10
-
最坏时间复杂度:my_list = [ 1 , 5 , 6 , 4 , 3 , 2 , 7 , 8 , 9 , 10 ]
-
最优时间复杂度:my_list = [ 10 , 5 , 6 , 4 , 3 , 2 , 7 , 8 , 9 , 1 ]
对于最优时间复杂度,其价值不大,因为它没有提供什么有用信息其反映的只是最乐观最理想的情况,没有参考价值。
对于最坏时间复杂度,提供了一种保证,表明算法在此种程度的基本操作中一定能完成工作
对于平均时间复杂度,是对算法的一个全面评价,因此它完整全面的反映了这个算法的性质。但另一方面,这种衡量并没有保证,不是每个计算都能在这个基本操作内完成。而且,对于平均情况的计算,也会因为应用算法的实例分布可能并不均匀而难以计算。
因此,我们主要关注算法的最坏情况,亦即最坏时间复杂度
1.4 常见的时间复杂度
执行次数函数举例 | 阶 | 非正式术语 |
---|---|---|
12 | O(1) | 常数阶 |
2n+3 | O(n) | 线性阶 |
3n2+2n+1 | O(n2) | 平方阶 |
5log2n+20 | O(logn) | 对数阶 |
2n+3nlog2n+19 | O(nlogn) | nlogn阶 |
6n3+2n2+3n+4 | O(n3) | 立方阶 |
2n | O(2n) | 指数阶 |
注意,经常将log2n(以2为底的对数)简写成logn
所消耗的时间从小到大:
O(1) < O(logn) < O(n) < O(nlogn) < O(n2) < O(n2logn) < O(n3) < O(2n) < O(n!) < O(nn)
2. 空间复杂度
空间复杂度S(n):该算法所耗费的存储空间
空间复杂度是对一个算法在运行过程中临时占用存储空间大小的度量
算法的时间复杂度和空间复杂度合称为算法的复杂度