算法基础篇 — 认识算法

什么是算法?

引用百度百科的一段话:算法(Algorithm)是指解题方案的准确而完整的描述,是一系列解决问题的清晰指令,算法代表着用系统的方法描述解决问题的策略机制。也就是说,能够对一定规范的输入,在有限时间内获得所要求的输出。如果一个算法有缺陷,或不适合于某个问题,执行这个算法将不会解决这个问题。不同的算法可能用不同的时间、空间或效率来完成同样的任务。一个算法的优劣可以用空间复杂度与时间复杂度来衡量。

在Java中,我是这样理解的。首先算法,需要解决某个描述性的问题。那么这个问题可大可小,大到满足产品特征性业务需求,小到简单的数据输入输出。

比如我需要对某一个样本数据进行排序,那么首先最原始的算法就是把所有的数都比较一遍,那么从时间复杂度来说效率肯定很低,如果这时候就有一个效率较高的算法来进行排序,并且输出结果与最原始的结果又完全正确,那么对于当前这个样本数据我肯定选择无限接近最优的算法。

在Java中,数据结构又会决定算法的适用场景,还需要根据时间复杂度,空间复杂度来择优算法。说了这些,本质是为了提高数据的产出效率。那么效率提现在哪呢?别急,下面会根据应用场景举例说明。

那么评估算法优劣的核心指标是什么?

  • 时间复杂度
  • 额外空间复杂度
  • 常数项时间

算法中常见的名词

时间复杂度

首先我们先抛开那些专业的理论。想象一下,当我们要计算数据样本量很大的时候,一昧的去计算每个细节计算的复杂度,那估计得算到恒星陨落去了。所以我们只看最高阶项那么就知道最坏的情况是多少时间复杂度了。举个例子,某两个时间复杂度计算公式为:

T(n) = an² + bn+c 或 T(n) = xn + yn + zn²

那么这两个公式的最高阶项都为n²,那么时间复杂度就是O(n²),这时候你就有疑问了,那我n都是常数1呢?这种情况就是时间复杂度最好的情况了,就不能用O(n²) 来衡量这个公式的复杂度了,但是这个公式始终也可能存在最坏的情况,不是常数1,那么用O(n²)来表示这个公式的时间复杂度就完全没问题了。所以决定某个算法的时间复杂度,与数据样本量有关系,和计算时间频度无关,即使是两个不同时间频度的公式,但时间复杂度也存在相同的情况。
我相信在各种博客都会聊到:

在各种不同算法中,若算法中语句执行次数为一个常数,则时间复杂度为O(1)。
按数量级递增排列,常见的时间复杂度有:常数阶O(1),对数阶O(log2n),线性阶O(n),线性对数阶O(nlog2n),平方阶O(n2),立方阶O(n3),…,
k次方阶O(nk),指数阶O(2n)。随着问题规模n的不断增大,上述时间复杂度不断增大,算法的执行效率越低。

关于这个理论实在是太长篇大论了,所以你只需要记住,只看最后计算公式的最高阶项,那么就是它的时间复杂度!

额外空间复杂度

实现一个算法,在实现算法的过程中,你需要开辟一些新的空间来支持你的算法,这就是额外空间。需要注意的是:

  • 作为输入参数的空间,不算额外空间。
  • 作为输出结果的空间,也不算额外空间。

因为实现算法过程中这些都是必要的,和实现目标有关。如果你的实现过程还需要开辟空间才能完全实现算法的流程,那么这就是额外空间。

如果你的额外空间就是几个临时变量,那么就是常数级别的操作,O(1)。如果你申请了一个与算法输入参数相同的空间,那么就是O(N)。

对数器

对算法准确性的校验。比如我们写了一个算法A,但是你一些简单的数据样本测试通过了,但是用复杂的数据样本测试的时候却报错了,但是又不知道错在哪,怎么办?

  • 实现一个时间复杂度效率较低的算法B,或者使用现成的算法API
  • 实现一个随机数据样本生成器
  • 使用相同的随机样本数据进行测试算法A和B,然后比较结果
  • 如果算法AB在某个随机样本下的结果不一致,则调试算法A,进行优化。
  • 优化完成后,算法A和B的结果不管随机多少数据样本都一样,那么可以确定这个算法A是正确的

常数项时间

引用百度百科的一段话:在计算复杂度理论中,常数时间是一种时间复杂度,它表示某个算法求出解答的时间在固定范围内,而不依照问题输入数据大小变化。常数时间记为O(1)(采用大O符号)。数字1可以替换为任意常数。

个人理解常数时间复杂度,在Java中是一些不因为数据量样本大小,而对数据操作为固定时间的算法操作就是常数级别的。比如以下例子:

  1. 数组寻址操作。比如想在 “访问数组上的元素” 的问题上达到常量时间,只要以元素的下标(index)访问即可。然而 “在数组上搜索最小值” 并不是一个常量时间问题,因为这需要扫描数组上的每一个元素以寻找最小值及其位置,一般需要O(n)次访问。

  2. 常见的算术运算(+、-、*、/、%)

  3. 常见的一些二进制计算(位移、异同或)

  4. 常见的 “值” 运算(赋值、比较、自增、自递减)

为什么自己写算法?

  • 算法与程序语言无关。
  • 程序语言具备的api无法满足需求时,需要手动改写。
  • 软件工具的底层依赖最基本的算法和数据结构。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
数据结构算法是计算机科学和软件工程领域中非常重要的基础知识。数据结构是指组织和存储数据的方式,而算法则是解决问题的一系列步骤。在这里,我将简要介绍数据结构算法基础知识。 1. 数组(Array):是一种线性数据结构,可以存储相同类型的元素。数组的特点是可以通过索引快速访问元素。 2. 链表(Linked List):也是一种线性数据结构,不同于数组,链表的元素在内存中可以不连续存储,每个元素包含一个指向下一个元素的指针。 3. 栈(Stack):是一种后进先出(LIFO)的数据结构,只能在栈的一端进行插入和删除操作。 4. 队列(Queue):是一种先进先出(FIFO)的数据结构,只能在队列的一端进行插入操作,在另一端进行删除操作。 5. 树(Tree):是一种非线性数据结构,由节点和边组成。树的一个节点可以有多个子节点。 6. 图(Graph):也是一种非线性数据结构,由节点和边组成。不同于树,图中的节点之间可以有多个连接。 7. 排序算法:常见的排序算法包括冒泡排序、选择排序、插入排序、快速排序、归并排序等,它们用于将一组元素按照特定的顺序进行排列。 8. 查找算法:常见的查找算法包括线性查找、二分查找等,它们用于在一组元素中查找特定的值。 以上只是数据结构算法基础知识,还有许多其他重要的概念和算法,如哈希表、堆、图算法等。掌握数据结构算法基础知识可以帮助我们更好地理解和解决实际的计算机问题

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值