【Java数据结构及算法实战】系列005:渐近记法

简介: 本节是《Java数据结构及算法实战》系列的第5节,主要介绍分析算法和数据结构的重要工具——渐近记法。在前一节,我们介绍了程序的性能,也介绍了评估性能的方式。那么,我们是否就能测算出算法需要运行的时间呢?

本节是《Java数据结构及算法实战》系列的第5节,主要介绍分析算法和数据结构的重要工具——渐近记法。

在前一节,我们介绍了程序的性能,也介绍了评估性能的方式。那么,我们是否就能测算出算法需要运行的时间呢?

1.3.1 大O标记法

直接回答上述问题并非易事,原因在于,即使是同一算法,针对不同的输入运行的时间并不相同。以排序问题为例,输入序列的规模、组成和次序都不是确定的,这些因素都会影响到排序算法的运行时间。在所有这些因素中,输入的规模是最重要的一个。假设我们要对学生按照成绩排序,那么显然,当学生的规模很少时(比如50个)所耗费的排序时间,肯定是要比当学生的规模很大时(比如50万个)所耗费的排序时间短。

因此,在实际分析算法的时间复杂度时,通常只考虑输入规模这一主要因素。如果将某一算法为了处理规模为n的问题所需的时间记作T(n),那么随着问题规模n的增长,运行时间T(n)我们将称之为算法的时间复杂度

由于小规模的问题所需的处理时间相对更少,不同算法在效率方面的差异并不明显,而只有在处理大规模的问题时,这方面的差异才有质的区别。因此,在评价算法的运行时间时,我们往往可以忽略其在处理小规模问题时的性能,转而关注其在处理足够大规模问题时的性能,即所谓的渐进复杂度(Asmpototic Complexity)。

另外,通常我们也不需要知道T(n)的确切大小,而只需要对其上界作出估计。比如说,如果存在正常数a、N和一个函数f(n),使得对于任何n > N,都有

T(n) < a × f(n) 

我们就可以认为在n足够大之后,f(n)给出了T(n)的一个上界。对于这种情况,我们记之为

T(n) = O(f(n))

这里的O称作“大O记号(Big-O notation)”,是希腊字母omicron的大写形式。从上述例子可以看出,大O记号实质上是对算法执行效率的一种保守估计⎯⎯对于规模为n的任意输入,算法的运行时间都不会超过O(f(n))。换言之,大O记号是对算法执行效率最差情况的估算。

大O记号是渐进记法的一种。渐进记法一直就是人们用于分析算法和数据结构的重要工具。其核心思想是:提供一种资源表示形式,主要用于分析某项功能在应对一定规模参数时需要的资源(通常是时间,有时候也会是内存)。常用的渐进记法还包括大Θ记号、大Ω记号。

1.3.2 大Ω标记法

如果存在正常数a、N和一个函数g(n),使得对于任何n>N,都有

T(n) > a × g(n) 

我们就可以认为在n足够大之后,g(n)给出了T(n)的一个下界。对于这种情况,我们记之为

T(n) = Ω(g(n)) 

这里的Ω称作“大Ω记号(Big-Ω notation)”,是希腊字母omega的大写形式。大Ω记号与大O记号正好相反,它是对算法执行效率的一种乐观估计⎯⎯对于规模为n的任意输入,算法的运行时间都不会低于Ω(g(n))。换言之,大O记号是对算法执行效率最好情况的估算。

1.3.3 大Θ标记法

如果存在正常数a<b、N和一个函数h(n),使得对于任何n > N,都有

a × h(n) < T(n) < b × h(n) 

我们就可以认为在n足够大之后,h(n)给出了T(n)的一个确界。对于这种情况,我们记之为

T(n) = Θ(h(n)) 

这里的Θ称作“大Θ记号(Big-Θ notation)”,是希腊字母theta的大写形式。大Θ记号是对算法执行效率的一种准确估计⎯⎯对于规模为n的任意输入,算法的运行时间都与Θ(h(n))同阶。

1.3.4 渐近记法总结

总结而言,渐近记法的含义如下表1-2所示。

表1-2 渐近记法含义

符号 含义
O 渐进小于或等于
Ω 渐进大于或等于
Θ 渐进等于

在上面度量算法复杂度的三种记号中,大O记号是最基本的,也是最常用到的。本书后续的算法复杂度也主要采用按照大O记号来表示。

参考引用

目录
相关文章
|
15天前
|
机器学习/深度学习 算法 数据挖掘
K-means聚类算法是机器学习中常用的一种聚类方法,通过将数据集划分为K个簇来简化数据结构
K-means聚类算法是机器学习中常用的一种聚类方法,通过将数据集划分为K个簇来简化数据结构。本文介绍了K-means算法的基本原理,包括初始化、数据点分配与簇中心更新等步骤,以及如何在Python中实现该算法,最后讨论了其优缺点及应用场景。
58 4
|
2月前
|
存储 人工智能 算法
数据结构与算法细节篇之最短路径问题:Dijkstra和Floyd算法详细描述,java语言实现。
这篇文章详细介绍了Dijkstra和Floyd算法,这两种算法分别用于解决单源和多源最短路径问题,并且提供了Java语言的实现代码。
90 3
数据结构与算法细节篇之最短路径问题:Dijkstra和Floyd算法详细描述,java语言实现。
|
2月前
|
存储 Java 开发者
Java Map实战:用HashMap和TreeMap轻松解决复杂数据结构问题!
【10月更文挑战第17天】本文深入探讨了Java中HashMap和TreeMap两种Map类型的特性和应用场景。HashMap基于哈希表实现,支持高效的数据操作且允许键值为null;TreeMap基于红黑树实现,支持自然排序或自定义排序,确保元素有序。文章通过具体示例展示了两者的实战应用,帮助开发者根据实际需求选择合适的数据结构,提高开发效率。
67 2
|
12天前
|
数据采集 存储 算法
Python 中的数据结构和算法优化策略
Python中的数据结构和算法如何进行优化?
|
9天前
|
Java 程序员
Java基础却常被忽略:全面讲解this的实战技巧!
小米,29岁程序员,分享Java中`this`关键字的用法。`this`代表当前对象引用,用于区分成员变量与局部变量、构造方法间调用、支持链式调用及作为参数传递。文章还探讨了`this`在静态方法和匿名内部类中的使用误区,并提供了练习题。
14 1
|
12天前
|
并行计算 算法 测试技术
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面,旨在通过综合策略提升程序性能,满足实际需求。
36 1
|
20天前
|
安全 Java 开发者
Java 多线程并发控制:深入理解与实战应用
《Java多线程并发控制:深入理解与实战应用》一书详细解析了Java多线程编程的核心概念、并发控制技术及其实战技巧,适合Java开发者深入学习和实践参考。
42 6
|
19天前
|
存储 安全 Java
Java多线程编程中的并发容器:深入解析与实战应用####
在本文中,我们将探讨Java多线程编程中的一个核心话题——并发容器。不同于传统单一线程环境下的数据结构,并发容器专为多线程场景设计,确保数据访问的线程安全性和高效性。我们将从基础概念出发,逐步深入到`java.util.concurrent`包下的核心并发容器实现,如`ConcurrentHashMap`、`CopyOnWriteArrayList`以及`BlockingQueue`等,通过实例代码演示其使用方法,并分析它们背后的设计原理与适用场景。无论你是Java并发编程的初学者还是希望深化理解的开发者,本文都将为你提供有价值的见解与实践指导。 --- ####
|
2月前
|
存储 消息中间件 安全
JUC组件实战:实现RRPC(Java与硬件通过MQTT的同步通信)
【10月更文挑战第9天】本文介绍了如何利用JUC组件实现Java服务与硬件通过MQTT的同步通信(RRPC)。通过模拟MQTT通信流程,使用`LinkedBlockingQueue`作为消息队列,详细讲解了消息发送、接收及响应的同步处理机制,包括任务超时处理和内存泄漏的预防措施。文中还提供了具体的类设计和方法实现,帮助理解同步通信的内部工作原理。
JUC组件实战:实现RRPC(Java与硬件通过MQTT的同步通信)
|
2月前
|
存储 缓存 算法
前端算法:优化与实战技巧的深度探索
【10月更文挑战第21天】前端算法:优化与实战技巧的深度探索
24 1