02-算法[笔记]

第二章 算法

一、算法

1.1 算法的描述

算法,是解决特定问题求解步骤的描述,在计算机中表现为指令的有限序列,并且每条指令表示的是一个或多个操作。

比如经典的问题,如何把大象装进冰箱里?

  1. 把冰箱打开
  2. 把大象装进冰箱
  3. 把冰箱关上

上面的描述就构成了一个简单的算法。

1.2 算法的特性

算法拥有五个基本特性:

  • 输入输出
  • 有穷性
  • 确定性
  • 可行性

对于算法的输入输入,要求的是算法至少有一个输出,可以没有输入,否则一个不与外界产生交互的算法没有任何意义。

有穷性是指算法的执行要在有限的步骤之下,而有限的步骤又必须在可接受的时间内完成,否则一个30年才能执行完毕的算法很难产生现实意义。

算法的确定性是指,每一个步骤必须是明确的,不能出现二义性,不能像一千个读者就有一千个汉姆雷特那样。

算法的可行性指算法设计的每一步都是具体可执行的,比如我给自己人生设计一个考上清华的算法,但是有一个步骤是每天学习24个小时,这完全就是荒唐了。

1.3 算法设计的要求

对于算法设计的也有五个要求:

  • 正确性
  • 可读性
  • 健壮性
  • 时间效率高和存储量低

就比如我们高中做题,一个优秀的解应该满足哪些条件?

第一,它必然是正确的,否则称不上解、也称不上优秀

第二,它必然是可阅读的,老师无法阅读你解的步骤就无法给你真实的评价

第三,它必然是健壮的,当某些不服气的同学拿一些极端情况去攻击你的解法时,你的解法要禁得起考验

第四,它必然要耗时短和足够的简洁,否则也称不上优秀的解嘛,聪明的人还是很多的

把算法特性和算法设计的要求画在一张思维导图上,明确它们之间的区分:

image-20220718212053506

依照我个人的理解,算法的特性是对算法本身的要求,算法设计的要求是对优秀算法的要求。

二、算法效率的度量方法

2.1 事后统计法

事后统计法,这种方法主要是通过设计好的测试程序和数据,利用计算机定时器对不同算法编制的程序的运行时间进行比较,从而确定算法效率的高低。

这个方法理解起来很简单,就跟运动员比赛跑步一样,同一起点、同一长度的赛道,谁先到终点谁速度快。

这种方法的优点就是简单直观,缺点罗列如下:

  1. 必须依据算法事先编制好程序,这一般而言要花费的功夫巨大
  2. 时间的比较依赖计算机硬件和软件等环境因素,有时会掩盖算法本身的优劣
  3. 算法的测试数据设计困难,并且程序的运行时间往往与测试数据的规模有很大关系

总之,事后估计法并没有被广泛的采纳,而是丢进了历史的垃圾桶里,而一种为今人广为称道的方法是事前分析估计方法

2.2 事前分析估计方法

事前分析估计方法,在计算机程序编制前,依据统计方法对算法进行估算。

分析两种求和算法:

第一种算法

int i, sum = 0, n = 100;   // 执行1次
for(i=1; i<=n; i++)        // 执行n+1次
{
	sum = sum + i;          // 执行n次
}
printf("%d\n", sum);       // 执行1次

第二种算法:

int sum = 0, n = 100;     // 执行1次
sum = (1 + n) * n/2;      // 执行1次
printf("%d\n", sum)       // 执行1次

第一种算法一共执行1+(n+1)+n+1=2n+3次,第二种算法执行1+1+1=3次,算法的好坏显而易见。

2.3 算法时间复杂度

在进行算法分析时,语句总的执行次数T(n)是关于问题规模n的函数,进而分析T(n)随n的变化情况并确定T(n)的数量级。

算法时间复杂度,也就是算法的时间量度,记作T(n)=O(f(n))。它表示随问题规模n的增大,算法执行的增长率和f(n)的增长率相同,称作算法的渐进时间复杂度,简称时间复杂度,其中f(n)是问题规模n的某个函数。

2.4 推导大O阶方法

推导大O阶:

  1. 用常数1取代运行时间中的所有加法常数
  2. 在修改后的运行次数函数中,只保留最高阶项
  3. 如果最高阶项存在且其系数不是1,则去除与这个项相乘的系数

得到的结果就是大O阶,按照我的理解就是找最高阶,并使最高阶的系数为1,其他项不用考虑。

2.5 常见的时间复杂度

执行次数函数非正式术语
12O(1)常数阶
2n+3O(n)线性阶
3n^2+2nO(n^2)平方阶
5log(n)+20O(log(n))对数阶
2n+3nlog(n)+19O(nlog(n))nlog(n)阶
6n3+2n2+3n+4O(n^3)立方阶
2^nO(2^n)指数阶

常见时间复杂度耗费时间从小到大排序如下:

O(1)<O(log(n))<O(n)<O(nlog(n))<O(n2)<O(n3)<O(2n)<O(n!)<O(nn)

^n | O(2^n) | 指数阶 |

常见时间复杂度耗费时间从小到大排序如下:

O(1)<O(log(n))<O(n)<O(nlog(n))<O(n2)<O(n3)<O(2n)<O(n!)<O(nn)

三、推荐

昨天在下班的路上,偶然看到一个电流表制作的视频,希望对大家的热爱有所帮助。

年轻人的,第二个电流表(完整开源)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

王山之

天青色等烟雨~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值