引入
编程处理问题时,可能有多种处理方法,那么衡量写出的程序的好坏的标准是什么?
结果正确、运行速度快、结构优美,算法设计合理都可以作为衡量标准。
什么是算法
程序=算法+数据结构
算法是对特定问题求解步骤的一种归纳描述。算法是解决问题的逻辑、方法、过程,数据结构是数据在计算机中的存储和访问方式。两者通常是紧密结合的。
算法具有5个特征:
-
输入
有零或多个输入。可以没有输入,比如只进行一些输出任务。
-
输出
有一个或多个输出。程序可以没有输入,但一定要有输出。 -
有穷性
在有限的步骤中结束。
-
确定性
每一条指令都有明确的含义,相同输入只能得到相同的结果。
-
可行性
算法描述的过程能通过已经实现的基本操作执行有限次来实现。(可以编程实现)
为什么要使用算法
可以站在巨人的肩膀上高效地解决问题。
如何评价算法的好坏
程序在运行时需要耗费两种资源,即计算时间和空间存储。资源是有限的,一个算法对两个资源的使用程度可以用来衡量该算法的优劣。
时间复杂度:程序运行时间的增速
空间复杂度:程序运行需要的存储空间的增速
问题的有效解决,不仅在于能否得到正确答案,更重要的是能在合理的时间和空间内给出答案。
衡量算法性能的主要标准是时间复杂度。
时间复杂度只是一个估计,并不需要精确计算。
大O表示法
O(操作数)
一种特殊的表示法,之处了算法的速度(增速)有多快。之所以称之为大O表示法,是因为操作数前面有个大O.
多项式复杂度
- O(1)
计算时间是一个常数,和问题的规模n无关。
- O(logn)
计算时间是对数,通常是以2为底的对数,每一步计算后,问题的规模缩小一倍。二分查找
-
O(n)
计算时间随规模n线性增长。简单的查找。
-
O(nlogn) 快速排序
-
O(n^2) 选择排序、冒泡排序。
指数复杂度
- O(2^n)
一般对应集合问题,例如一个集合中有n个元素,求出它所有的子集,子集有2^n个。
- O(n!)
时间复杂度指最糟糕情况下的运行时间。
如何计算时间复杂度
对于输入规模为n的算法,我们可以统计它的基本操作执行次数,来对其效率进行度量.
找出算法中最重要的操作,即所谓的基本操作,它们对总运行时间的贡献最大,然后计算他们的运行次数。
不难发现,一个算法的基本操作往往是算法最内层循环中最费时的操作。
-
找出语句中的基本语句
-
计算基本语句的执行次数的数量级
只需计算基本语句执行次数的数量级,这就意味着只要保证基本语句执行次数的函数中的最高次幂正确即可,可以忽略所有低次幂和最高次幂的系数。这样能够简化算法分析,并且使注意力集中在最重要的一点上:增长率。
-
用大O记号表示算法的时间性能
将基本语句的执行次数的数量级放入大O记号中,形如O(数量级)
如何选择算法
对于同一个问题,经常存在不同的解决方案,有高效的,也有低效的。算法编程竞赛主要的考核点就是在限定的时间和空间内解决问题。通常时间限制为1s。1s计算机执行的次数约在106~108,所以,在知道程序复杂度后,根据数据范围可以大体估算出程序的运行时间,从而辅助我们判断该算法能否满足时间要求。