大话数据结构学习笔记之(2) - 算法
定义
算法(Algorithm): 解决特定问题求解步骤的描述,在计算机中表现为指令的有限序列,并且每条指令表示一个或多个操作
算法的特性
- 输入输出:算法具有零个或多个输入,至少有一个或多个输出
- 有穷性: 指算法在执行有限的步骤之后,自动结束而不会出现无限循环,并且每一个步骤在可接受的时间内完成。
- 确定性: 算法的每一步骤都具有确定的含义,不会出现二义性
- 可行性: 算法的每一步都必须是可行的,即每一步都能够通过执行有限次数完成
算法设计的要求
- 正确性: 算法的正确性是指算法至少应该具有输入、输出和加工处理无歧义性、能正确反映问题的需求、能够得到问题的正确答案。
- 可读性: 算法设计的另一目的是为了便于阅读、理解和交流
- 健壮性: 当输入数据不合法时,算法也能做出相关处理,而不是产生异常或莫名其妙的结果
- 时间效率高和存储量低:即执行时间和存储空间
算法效率的度量方法
事前分析估算方法
在计算机程序编制前,依据统计方法对算法进行估算。一个程序的运行时间,依赖于算法的好坏和问题的输入规模即输入量的多少
求和算法
1
int i, sum = 0, n = 100; // 执行 1 次 for(i = 1; i <= n; i++) // 执行了 n+1 次 sum = sum + i; // 执行 n 次 printf("%d", sum); // 执行 1 次
求和算法
2
int sum = 0, n = 100; // 执行一次 sum = (1 + n) * n / 2; // 执行一次 printf("%d", sum); // 执行一次
对上述连个算法,忽略头尾循环判断的开销,就是n
次与1
次的差距, 算法好坏显而易见
算法时间复杂度
在进行算法分析时,语句总的执行次数
T(n)
是关于问题规模n
的函数, 进而分析T(n)
随n
的变化情况并确定T(n)
的数量级。 算法的时间复杂度,也就是算法的时间量度,记作;T(n) = O(f(n))
。 它表示随问题规模n
的增大,算法执行时间的增长率和f(n)
的增长率相同,称作算法的渐进时间复杂度,简称为时间复杂度。其中f(n)
是问题规模n
的某个函数
推导大O
阶方法
- 用常数
1
取代运行时间中的所有加法常数 - 在修改后的运行次数函数中,只保留最高阶项
- 如果最高阶项存在且不是
1
, 则去除与这个项相乘的常数
得到的结果就是大O
阶
常数阶
求和算法2
中,运行次数函数为O(3)
,根据推导大O
阶方法,得到时间复杂度为O(1)
线性阶
求和算法1
中,算法的时间复杂度为O(n)
对数阶
int count = 1;
while(count < n)
count = count * 2;
由
平方阶
int i, j;
for(i = 0; i < m; i++)
for(j = 0; j < n; j++)
{
/* 时间复杂度为 O(1) 的程序步骤序列 */
}
循环嵌套, 故时间复杂度为
m=n
, 则时间复杂度为
常见的时间复杂度
从
n
都会使的结果变得不显示
最坏情况与平均情况
最坏情况运行时间是一种保证,那就是运行时间将不会再坏了。一般提到的运行时间都是最坏情况的运行时间。平均运行时间是所有情况中最有意义的,因为它是期望的运行时间
算法空间复杂度
算法的空间复杂度通过计算算法所需的存储空间实现,算法空间复杂度的计算公式记作:
, 其中n
为问题的规模,f(n)
为语句关于n
所占存储空间的函数
结语
算法的基本概念,比如其定义、特性、设计要求、度量方法等。还有推导大O
阶,以及常见的时间复杂度以及关于算法最坏情况的概念