首页
技术小册
AIGC
面试刷题
技术文章
MAGENTO
云计算
视频课程
源码下载
PDF书籍
「涨薪秘籍」
登录
注册
第 13章 性能测量和大O算法分析
13.1 timeit模块
13.2 cProfile分析器
13.3 大O算法分析
13.4 大O阶
13.4.1 使用书架打比方描述大O阶
13.4.2 大O 测量的是最坏情况
13.5 确定代码的大O 阶
13.5.1 为什么低阶项和系数不重要
13.5.2 大O 分析实例
13.5.3 常见函数调用的大O 阶
13.5.4 一眼看出大O 阶
13.5.5 当n 很小时,大O并不重要,而n通常都很小
第 14章 项目实战
14.1 汉诺塔
14.1.1 汉诺塔输出
14.1.2 汉诺塔源代码
14.1.3 汉诺塔编写代码
14.2 四子棋
14.2.1 四子棋输出
14.2.2 四子棋源代码
14.2.3 四子棋编写代码
第 15章 面向对象编程和类
15.1 拿现实世界打比方:填写表格
15.2 基于类创建对象
15.3 创建一个简单的类——WizCoin
15.3.1 方法__init__()和self
15.3.2 特性
15.3.3 私有特性和私有方法
15.4 函数type()和特性__qualname__
15.5 非OOP 和OOP 的例子:井字棋
15.6 为现实世界设计类是一件难事儿
第 16章 面向对象编程和继承
16.1 继承的原理
16.1.1 重写方法
16.1.2 super()函数
16.1.3 倾向于组合而非继承
16.1.4 继承的缺点
16.2 函数isinstance()和issubclass()
16.3 类方法
16.4 类特性
16.5 静态方法
16.6 何时应该使用类和静态的面向对象特性
16.7 面向对象的行话
16.7.1 封装
16.7.2 多态性
16.8 何时不应该使用继承
16.9 多重继承
16.10 方法解析顺序
第 17章 Python 风格的面向对象编程:属性和魔术方法
17.1 属性
17.1.1 将特性转换为属性
17.1.2 使用setter 验证数据
17.1.3 只读属性
17.1.4 什么时候应该使用属性
17.2 Python 的魔术方法
17.2.1 字符串表示魔术方法
17.2.2 数值魔术方法
17.2.3 反射数值魔术方法
17.2.4 原地魔术方法
17.2.5 比较魔术方法
当前位置:
首页>>
技术小册>>
Python编程轻松进阶(五)
小册名称:Python编程轻松进阶(五)
### 13.5.4 一眼看出大O阶 在Python编程的世界中,算法的效率是衡量程序性能的关键指标之一。而算法的时间复杂度,尤其是大O表示法(Big O Notation),是评估算法效率最直接的方式。掌握如何“一眼看出”算法的大O阶,对于程序员来说,不仅是进阶技能的体现,更是解决实际问题时优化代码、提升性能的必备能力。本章节将深入剖析大O阶的本质,通过实例演示如何快速判断算法的时间复杂度。 #### 1. 大O阶概述 大O阶,又称为时间复杂度的大O表示法,是一种用来描述算法执行时间随输入规模增长而变化的渐近上界的方法。它并不表示算法执行的确切时间,而是给出了一个“最坏情况”下时间增长的趋势。大O阶的“O”代表Order of(...的量级),用于描述算法的时间消耗与输入规模之间的函数关系。 #### 2. 常见的大O阶 在深入学习如何快速判断算法的大O阶之前,我们先来回顾一些常见的大O阶及其含义: - **O(1)**:常数时间复杂度,表示算法的执行时间不受输入规模影响,始终是一个常数。 - **O(log n)**:对数时间复杂度,随着输入规模n的增长,算法执行时间以对数形式增长。 - **O(n)**:线性时间复杂度,算法的执行时间与输入规模n成正比。 - **O(n log n)**:线性对数时间复杂度,是介于线性与多项式时间复杂度之间的中间情况。 - **O(n^2)**、**O(n^3)**、...、**O(n^k)**:多项式时间复杂度,随着输入规模n的增长,算法执行时间以多项式形式增长,其中k为常数。 - **O(2^n)**、**O(n!)**:指数时间复杂度和阶乘时间复杂度,表示算法执行时间随着输入规模的增长而急剧增加,通常认为是不高效的。 #### 3. 判断大O阶的技巧 ##### 3.1 识别基本操作 首先,识别算法中的基本操作,即算法中重复执行次数最多的那部分代码。这些操作通常是算法性能的主要瓶颈。 ##### 3.2 估算基本操作执行次数 接下来,估算基本操作随输入规模n变化时的执行次数。这通常需要观察算法的逻辑结构,如循环、递归等,并考虑它们如何影响基本操作的执行次数。 ##### 3.3 忽略低阶项和常数项 在估算过程中,可以忽略掉执行次数与n相比增长较慢的低阶项,以及常数项。这是因为当n足够大时,这些项对总执行时间的影响将变得微不足道。 ##### 3.4 识别并应用常见模式 许多算法都遵循一定的模式,如二分查找、冒泡排序、归并排序等。熟悉这些模式及其对应的时间复杂度,可以大大加快判断大O阶的速度。 #### 4. 实例分析 为了更直观地展示如何判断算法的大O阶,我们将通过几个实例进行分析。 ##### 4.1 线性查找 ```python def linear_search(arr, target): for i in range(len(arr)): if arr[i] == target: return i return -1 ``` 在线性查找算法中,基本操作是`if arr[i] == target:`这一行的比较操作。该操作在数组中每个元素上执行一次,因此基本操作执行次数为n(数组的长度)。所以,线性查找的时间复杂度为O(n)。 ##### 4.2 二分查找 ```python def binary_search(arr, target): low, high = 0, len(arr) - 1 while low <= high: mid = (low + high) // 2 if arr[mid] == target: return mid elif arr[mid] < target: low = mid + 1 else: high = mid - 1 return -1 ``` 在二分查找算法中,每次循环都将搜索范围减半,因此基本操作(即比较操作)的执行次数与二分查找树的深度相同,即log2(n)。所以,二分查找的时间复杂度为O(log n)。 ##### 4.3 冒泡排序 ```python def bubble_sort(arr): n = len(arr) for i in range(n): for j in range(0, n-i-1): if arr[j] > arr[j+1]: arr[j], arr[j+1] = arr[j+1], arr[j] ``` 冒泡排序中,有两层嵌套循环。外层循环控制排序的轮数,内层循环进行实际的比较和交换操作。对于每一轮排序,内层循环都需要执行n-i-1次(i为外层循环的当前轮数)。因此,总的基本操作执行次数可以近似为n*(n-1)/2,即O(n^2)。 #### 5. 总结与提升 通过上述实例分析,我们可以看到,判断算法的大O阶需要理解算法的基本结构和逻辑,并能够准确估算基本操作随输入规模变化的执行次数。随着经验的积累,你将能够更加快速地识别出算法的时间复杂度,甚至在没有具体代码的情况下,仅凭算法的描述或伪代码就能做出准确的判断。 此外,值得注意的是,虽然大O阶是衡量算法效率的重要指标,但在实际应用中,还需要考虑算法的空间复杂度、数据的初始状态、系统的具体环境等多种因素。因此,在优化算法时,应综合考虑多方面因素,以达到最佳的性能表现。 最后,建议读者通过大量的练习来巩固所学知识,尝试自己编写算法并分析其时间复杂度,或者分析现有算法的时间复杂度,以此来提升自己的编程能力和问题解决能力。随着实践经验的积累,你将能够越来越熟练地“一眼看出”算法的大O阶,从而在编程道路上更加游刃有余。
上一篇:
13.5.3 常见函数调用的大O 阶
下一篇:
13.5.5 当n 很小时,大O并不重要,而n通常都很小
该分类下的相关小册推荐:
Python合辑10-函数
Python机器学习实战
实战Python网络爬虫
机器学习算法原理与实战
Python高性能编程与实战
Python合辑1-Python语言基础
Python合辑13-面向对象编程案例(上)
Python数据分析与挖掘实战(上)
Python编程轻松进阶(三)
Python编程轻松进阶(四)
Python合辑9-判断和循环
Python合辑11-闭包函数