算法【Algorithm】:描述解决问题的方法;
算法的五个特性:输入、输出、有穷性、确定性、可行性
- 输入输出:算法至少有一个或多个输出
- 有穷性:指算法在执行有限的步骤之后,自动结束而不会出现无限循环
- 确定性:算法的每一个步骤都具有确定的含义,不会出现二义性
- 可行性:算法的每一步都必须是可行的
算法设计的要求:
- 正确性:算法的正确性是指算法至少应该具有输入、输出和加工处理无歧义性、能正确反映问题的需求、能够得到问题的正确答案。
- 可读性:算法设计的另一目的是为了便于阅读、理解和交流。
- 健壮性:一个好的算法还应该能对输入数据不合法的情况做合适的处理。
- 时间效率高和存储量低:
重点来了重点来了-----------------------------------------------------------------------------------------------------------------
算法时间复杂度 T(n) = O(f(n))
它表示随问题规模n的增大,算法执行时间的增长率和f(n)的增长率相同
执行次数 | 函数阶 | 非正式术语 |
12 | O(1) | 常数阶 |
2n+3 | O(n) | 线性阶 |
3n2+2n+4 | O(n2) | 平方阶 |
5log2 n+20 | O(logn) | 对数阶 |
2n+3nlog2 n+19 | O(nlogn) | nlogn阶 |
耗费的时间从小到大排序:O(1)<O(logn)<O(n)<O(nlogn)<O(n的n次方)
常数阶
int sum = 0,n = 100; 执行一次
sum = (1+n) * n /2; 执行一次
printf("%d",sum); 执行一次
f(n)=3。根据我们推导大O阶的方法,第一步就是把常数项3改为1.在保留最高阶时发现,它根本没有最高阶项,所以这个算法的时间复杂度为O(1).记住,不管这个常数是多少,我们都记做O(1)
线性阶
int i
for (i=0;i<n;i++)
{
时间复杂度为o(1)的程序步骤序列
}
总共需要执行n次 时间复杂度为O(n)
对数阶
int count = 1
while(count < n)
{
count = count * 2
}
由于每次count乘以2之后,就距离n更近了一分,也就是说,有多少个2相乘后大于n,则会推出循环。由2x=n==》x=log2 n 所以时间复杂度为O(logn)
平方阶
int i,j
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
时间复杂度为O(1)的程序步骤序列
}
}
当i=0时,内循环执行了n次
当i=1时,执行了n-1次
。。。
当i=n-1时,执行了1次
n+(n-1)+(n-2)+...+1 = n(n+1)/2=n2/2+n/2
推导大O阶的方法
1、没有加法常数不予考虑
2、只保留最高阶n2/2
3、去除这个项相乘的次常数
最终这段代码的时间复杂度为O(n2)
补充高中的数学知识点:
等差数列的通项公式为:an=a1+(n-1)d
前n项和公式为:Sn=na1+n(n-1)d/2或Sn=n(a1+an)/2
等比数列通项公式 q=1 an=a1
q不为1时 an=a1*q^(n-1)
q=1时,Sn=na1
q不等于1时,
Sn=a1*(1-q^n)/(1-q)