目录
数据结构+算法=程序
数据结构是程序的骨架,算法是程序的灵魂。
算法
概念
算法是对特定问题求解步骤的一种描述。
特性
- 有穷性:算法是由若干条指令组成的有穷序列,总是在执行若干次后结束,不可能永不停止;
- 确定性:每条语句都有确定的含义,无歧义;
- 可行性:算法在当前环境条件下可以通过有限次运算来实现;
- 输入/输出:有零个或多个输入以及一个或多个输出;
“好”算法的标准
- 正确性;
- 易读性;
- 健壮性;
- 高效性(涉及“时间复杂度”);
- 低存储性(涉及“空间复杂度”);
时间复杂度(算法运行需要的时间)
衡量标准:算法基本运算的执行次数。
最坏情况对衡量算法的好坏具有实际意义。
O(f(n))表示时间复杂度渐近上界:
O(f(n))表示时间复杂度渐近下界:
空间复杂度(算法占用的空间大小)
衡量算法空间复杂度的关键因素:算法在运行时所使用的辅助变量占用的空间(即辅助空间)。
算法占用的存储空间包括:
- 输入/输出数据;
- 算法本身;
- 额外需要的辅助空间;
注意:在递归算法中,每一次递推都需要一个栈空间来保存调用记录,因此在分析算法的空间复杂度时,需要计算递归栈的辅助空间。
常见的算法时间复杂度
- 常数阶
常数阶算法的运行次数是一个常数,如5、20、100。常数阶算法的时间复杂度通常用O()表示。
- 多项式阶
很多算法的时间复杂度是多项式,通常用O()、O(
)、O(
)等表示。
- 指数阶
指数阶算法的运行效率极差,程序员往往像躲"恶魔"一样避开这种算法。指数阶算法的时间复杂度通常用O()、O(
)、O(
)等表示。
- 对数阶
对数阶算法的运行效率较高,通常用O()、O(
)等表示,指数阶增量随着x的增加而急剧增加,而对数阶增长缓慢。
它们之间的关系如下:
O()< O(
)< O(
)< O(
)< O(
)< O(
)< O(
)< O(
)< O(
)
在设计算法时,我们要尽量避免爆炸级增量。
算法题(神奇的兔子数列)
兔子数列即斐波那契数列,它的发明者是意大利数学家菜奥纳尔多·斐波那契(Leonardo Fibonacci,1170—1250)。1202年,莱奥纳尔多撰写了《算盘全书》(Liber Abaci),该书是一部较全面的初等数学著作。书中系统地介绍了印度—阿拉伯数码及其演算法则,以及中国的“盈不足术";此外还引入了负数,并研究了—些简单的一次同余式组。
-
思想
-
算法
以下算法的时间复杂度为,空间复杂度为
//算法
int Fib3(int n){
if(n==1||n==2)
return 1;
int s1=1;//用s1和s2记录前面的两项
int s2=1;
for(int i=3;i<=n;i++){
int tmp=s1+s2;
s1=s2;
s2=tmp;
}
return s2;
}
实质上,斐波那契数列的时间复杂度还可以降到对数阶
注:如有任何不妥之处,请评论或私信告知,谢谢!