当前课程知识点:数据结构(上) > 第一章 绪论(上) > (c)大O记号 > 01c-2: 大O记号
为此我们可以采用所谓的大O记号big-O notation
来从形式上简化我们刚才所说的
度量时间成本的T(n)的表示
具体来说 在满足一些条件以后
我们可以在big-O的意义下
将大写的T(n)表示为某一个f(n)函数
什么条件呢?
这个充要条件就是
我们存在一个预先确定的一个常数C
而且确实 当n足够大之后 我们就会发现
T(n)绝对不会超过F(n)的c就是常数倍
这样的话就有可能使得我们更为简便地
界定一个算法的复杂度
我们可以来看这样一个例子
假设我们已经得到了
这样一个T(n)的表达式
那么我们可以看到 这个表达式
像通常的一样 总是会显得略微复杂
我们不容易抓住其中主要的脉络
为此我们可以采用
刚才所说的那个办法 不断地简化
大家注意 这里我们用的是小于号
也就是说 我们可以不断地
对函数大写的T(n)做放大
比如说 我们先把其中这个2替换成n
刚才我们说了 n足够大以后
是会远远地大于2的
我们不妨替换成它
那么很快我们就可以看到
这个地方就是2n
这就是为什么我们可以将这个
经过依次放大之后
转化为6的n方
接下来我们再采用这种办法
对4做一个放大
我们同样的把它放大成n方
这就是为什么有一个7n方
乘上前面的5n以后 我们说
可以得到一个35倍的n的立方
接下来 我们再对6做一次放大
放大成n的立方
这样的话 我们可以得到
36倍的n的立方
这就是为什么我们说
大概是等于6倍的n的3/2次方
我们说 因为这里还有一个常数
而这里可以看到
其实常数是无所谓的
所以我们可以把这个6进一步地抹去
从而通过在外面再加一个big-O记号
来完成这样的一个估计
刚才那个例子已告诉我们
经过这样的一次变换以后
big-O内 用来近似的那个函数f(n)
将会更加地简捷
而且 同时它也依然能够
准确地反应前者的增长趋势
根据这样的一个定义
这样的一个充要条件
我们可以得出
关于大O记号的两个重要的处理的手法
第一个 任何这种函数的常系数是可以忽略掉的
就像这样 可以视为1
第二个方面 低次项也是可以忽略掉的
也就是说 如果一个表达式可以表示
或者是至少展开成
这样的一个多项式的形式
其中的低次项
比如说b相对于a 略要小一些
低次项 n的b次方 是可以忽略掉的
从这里 我们也再次看得出来
我们前面所讲过的 所谓的长远
是体现在n足够大
而所谓的主流 就体现在
所有这些常系数和低次项
我们说 非主流一些旁枝末节的因素
都可以在此忽略
使得主流的信息能够突出出来
我们依然用一个图来表示
这个图是在原来那个基础上
增加了一个big-O的这样一条虚线
我们可以从这个图很好地看出来
big-O所设计和定义的用意
也就是说 它可以理解为
在上方给出了T(n) 也就是
我们说的这个时间复杂度的一个上界
也就是upper bound
所以 我们也可以认为big-O
是对T(n)的一个悲观的估计
这里我们再次提醒大家
注意这个图所画的用意
大家可以看到在n规模比较小的区域内
我们说这个T(n)未必一定
在big-O这个曲线的下方
其实这里还有一个含义
我们没有通过这个图画出来
也就是说 实际上这个big-O的upper bound的这条线
完全是可以在常系数的意义下的
它在准确的数值上 未必是低于大写的T(n)
只要预先约定好的一个常系数c
它经过放大能够完成构成上界的功能
就可以了
所以 这是我们所说的大O记号
我们可以看到非常地简明
-选课之前
--写在选课之前
--宣传片
-考核方式
--考核方式
-OJ系统说明
--关于OJ
--1-注册与登录
--2-界面与选课
--3-提交测试
-关于课程教材与讲义
--课程教材与讲义
-关于讨论区
--关于讨论区
-微信平台
--html
-PA晋级申请
--PA晋级
-(a)计算
--演示
--(a)计算--作业
-(b)计算模型
-(b)计算模型--作业
-(c)大O记号
-(c)大O记号--作业
-(d)算法分析
-(d)算法分析--作业
-(e)迭代与递归
-(e)迭代与递归--作业
-(xc)动态规划
-- 演示
-(xc)动态规划--作业
-本章测验--作业
-(a)接口与实现
--02A-5 复制
-(a)接口与实现--作业
-(b)可扩充向量
-(b)可扩充向量--作业
-(c)无序向量
--02C-1 概述
--02C-3 插入
--02C-6 查找
--02C-8 遍历
-(c)无序向量--作业
-(d1)有序向量:唯一化
-(d1)有序向量:唯一化--作业
-(d2)有序向量:二分查找
-(d2)有序向量:二分查找--作业
-(d3)有序向量:Fibonacci查找
-(d3)有序向量:Fibonacci查找--作业
-(d4)有序向量:二分查找(改进)
-(d4)有序向量:二分查找(改进)--作业
-(d5)有序向量:插值查找
-第二章 向量(下)--(d5)有序向量:插值查找
-(e)起泡排序
--02E-2 改进
--02E-3 反例
-(e)起泡排序--作业
-(f)归并排序
-(f)归并排序--作业
-本章测验--作业
-(a)接口与实现
--03A-4 实现
-(a)接口与实现--作业
-(b)无序列表
--03B-2 查找
-(b)无序列表--作业
-(c)有序列表
--03C-3 查找
-(c)有序列表--作业
-(d)选择排序
--03D-1 构思
--03D-2 实例
--03D-3 实现
--03D-4 推敲
--03D-6 性能
-(d)选择排序--作业
-(e)插入排序
--03E-1 经验
--03E-2 构思
--03E-3 对比
--03E-4 实例
--03E-5 实现
-(e)插入排序--作业
-(xd)习题辅导:LightHouse
-本章测验--作业
- (a)栈接口与实现
--04A-1 栈
--04A-2 实例
--04A-3 实现
- (a)栈接口与实现--作业
-(c1)栈应用:进制转换
-第四章 栈与队列--(c1)栈应用:进制转换
-(c2)栈应用:括号匹配
-(c2)栈应用:括号匹配--作业
-(c3)栈应用:栈混洗
-第四章 栈与队列--(c3)栈应用:栈混洗
-(c4)栈应用:中缀表达式求值
-(c4)栈应用:中缀表达式求值--作业
-(c5)栈应用:逆波兰表达式
-第四章 栈与队列--(c5)栈应用:逆波兰表达式
-(d)队列接口与实现
--04D-1 接口
--04D-2 实例
--04D-3 实现
-第四章 栈与队列--本章测验
-(a)树
--05A-1 动机
--05A-2 应用
-(a)树--作业
-(b)树的表示
--05B-2 父亲
--05B-3 孩子
-第五章 二叉树--(b)树的表示
-(c)二叉树
-(c)二叉树--作业
-(d)二叉树实现
-(d)二叉树实现--作业
-(e1)先序遍历
-(e1)先序遍历--作业
-(e2)中序遍历
-第五章 二叉树--(e2)中序遍历
-(e4)层次遍历
-第五章 二叉树--(e4)层次遍历
-(e5)重构
-(e5)重构--作业
-本章测验--作业
-(a)概述
-(a)概述--作业
-(b1)邻接矩阵
-(b1)邻接矩阵--作业
-(c)广度优先搜索
--06C-2 策略
--06C-3 实现
--06C-5 实例
-(c)广度优先搜索--作业
-(d)深度优先搜索
--06D-1 算法
--06D-2 框架
--06D-3 细节
-(d)深度优先搜索--作业
-第六章 图--本章测验