1、算法的概念
算法是指对特定问题求解步骤或思路的描述。我们举一个日常例子阐述如下:
问题:如何做一盘西红柿炒鸡蛋?
解决步骤或思路:
第一步,把西红柿洗干净并切片;
第二步,把西红柿放到锅里炒,然后备用;
第三步,将鸡蛋放到锅里炒,同时把炒好的西红柿放入锅中一起翻炒;
第四步,翻炒3分钟后,放到盘子中。
以上四步,就是对解决问题的步骤描述,也可以称之为解决问题的算法。需要说明的是,
- 针对特定问题,可以有很多种解决的方法或思路,对应的也就会有多种算法。
- 算法不是程序,程序是一序列指令的集合,但程序可以描述算法、实现算法。
2、算法的特征
一般而言,一个算法具有以下5个基本特征:
- 可行性,即按照算法所描述的步骤,是可以确定解决问题的,实现预期目标;
- 确定性,即算法所描述的步骤是清晰明确的,不存在歧义或模棱两可的地方,在任何情况下,给出特定的输入,算法总是给出相同的结果;
- 有穷性,即算法总是在执行有穷步骤后结束,且每一步都可以在有穷的时间内完成;
- 输入,即算法总有零个或多个输入;
- 输出,即算法总有一个或多个输出,且这些输出和输入有着某些特定的关系;
3、算法的复杂度
针对特定的问题,总是会有多种解决办法(即多种算法),那么,哪种算法是好的算法呢?又应该如何选择算法呢?这里就会使用到算法的评价标准了,即算法的时间复杂度和空间复杂度。
(1)时间复杂度
算法的时间复杂度是用来表示算法的时间效率的,即针对特定问题(同样的输入),解决问题所需时间越短,则说明该算法的时间效率越高。一个算法所花费的时间又与算法中操作的执行次数成正比,所以我们可以用算法中操作执行的次数来表示算法的时间效率。一般情况下,针对特定的算法,该算法中基本操作重复执行的次数是问题规模n的某个函数,记为T(n),若有某一个辅助函数f(n),当n无限接近于无穷大时,有T(n)/f(x)的极限值为不等于零的常数,则成f(n)是T(n)的同数量级函数。记做T(n)=O(f(n)),称O(f(n))为算法的渐进时间复杂度,简称时间复杂度。
我们举个例子来阐明,假设有一个算法,描述如下:
{ //循环1
重复执行N次
{
重复执行N次
{
打印 “ hello world!” ;
}
}
//循环2
重复执行N次
{
打印 “ hello world!” ;
}
}
在这个算法中,总共有两个循环语句,第一个循环语句是打印N2次‘hello world’,第二个循环语句是打印N次‘hello world’。打印‘hello world’这个语句是此算法中的基本操作。当问题规模为n时,基本操作次数就是T(n)=n2+n。那么我们可以找到一个函数f(n)=n2当n无穷大时,
,其极限值为不等于零的1,所以可以将f(n)=n2称为T(n)=n2+n函数的同数量级函数,则该算法的时间复杂度就为O(n2)。
常用的算法时间复杂度及其大小排序如下:
Ο(1)<Ο(log2n)<Ο(n)<Ο(nlog2n)<Ο(n2)<Ο(n3)<…<Ο(2n)<Ο(n!)
(2)空间复杂度
类似的,算法的空间复杂度是用来表示算法的存储效率的,即针对特定问题(同样的输入),解决问题所需存储空间越少,则说明该算法的空间效率越高。一般情况下,针对特定的算法,该算法运行中所占用的存储空间是问题规模n的某个函数,记为S(n),若有某一个辅助函数f(n),当n无限接近于无穷大时,有S(n)/f(x)的极限值为不等于零的常数,则成f(n)是S(n)的同数量级函数。记做S(n)=O(f(n)),称O(f(n))为算法的渐进空间复杂度,简称空间复杂度。