当前课程知识点:数据结构(上) > 第一章 绪论(上) > (c)大O记号 > 01c-3: 高效解
在大O记号定义的这杆直尺上
到底有哪些刻度呢?
我们首先来看,第一个刻度
也就是所谓的常数复杂度
我们把它记作O(1)
哪些是常数复杂度呢?
我们说常数,包括较大的常数
以及常数按照通常的四则混合运算
经过运算以后得到的常数
甚至常数的更高阶的一些运算的结果
从理论上讲,我们也依然认为是常数
尽管像这个,比如2000的2000次方
在实际中,已经是大的不能再大的一个数
是不能被忽略的
如果有算法 能够达到这样的复杂度
我们说这是再好不过的了
否则 什么都不用做
就得到计算结果
我们说那是不可能的
那是不劳而获
从代码段的形式上来看
哪些算法,是符合这种复杂度呢?
我们说如果一段代码中不含
显式的或者隐式的循环
具体来讲,就是由分支判断构成的代码体
那么,它必然是顺序执行的
总体而言 它必然是O(1)的复杂度
那么反之呢?
我们说情况并不那么简单
有很多时候,虽然它从形式这样讲
包含循环
但是未必会造成更大的复杂度
有的时候,虽然既有条件判断,也有转向
表面看,是有一个转向的可能
但也许因为语义上的某种限制
其实,它转向的目标是根本不可能达到的
还有一些呢 也同样会出现这种情况
比如说,隐式的循环,也就是所谓的递归
也会出现类似的情况
这些问题 在这里我们不再展开地介绍
有兴趣的同学,同样可以去参考我们的教材
以及习题解析
在那里有较为详细的介绍
接下来的一个刻度
是所谓的对数或者叫对数多项式复杂度
我们先来看对数
也就是说n,问题的规模的对数
很有意思的是 我们在这里,
往往不再标明具体的底数 为什么呢?
因为在底数为常数的情况下
其实具体是多少,在这里是无所谓的
我们来看一下这其中的原因
如果有一个表示原来是以a作为底数的
我们完全可以通过这样的一个等价变换
把它变换成,以b作为底数的
而为此所作的调整
无非是在前面乘了这么样一个
log以a为底b的对数
那么我们刚才讲过a和b都是常数
所以经过混合运算以后也是常数
我们说过在big-O
甚至严格地讲,在θ的意义上讲
这个常系数都是可以忽略掉的
所以我们说,具体到底是a还是b
其实是无所谓的
只要它们都是常数
与其如此,我们不如干脆就把它们忽略掉
不再具体标明
相应地呢
还有,我们另一个特征就是
如果这个n,也就是问题的规模
本身是呈一个幂指数的形式
它有一个常数次方
我们说这个在log n的掩盖下
也是可以忽略掉的
原因也很简单
在高中就应该学过这个
n的肩膀上这个c是可以等价地
挪到log前边去,变成一个常系数
没错,又是常系数
所以它也是可以被忽略掉的
当然,对数本身也可以呈现出多项式的形式
比如说对数的若干次方,构成一项
然后可能另一个次方,多少次项
那么在这种情况下
我们同样可以参照刚才
big-O的那种处理的方法
把低次的项 相对来说是
常系数的那些项都忽略掉
从而同样可以得到一个简明的
log的多项形式
所以我们把这个叫poly-log function
这类算法,我们说也是非常高效
因为从渐近地意义上讲
我们可以证明,对于任何一个多项式
哪怕是次数很低,
只要它是正数,一个次数c
logn都是可以在大O记号的意义下
被n的c次方所掩盖的
所以它应该是,低于任何多项式的一个复杂度
从这个意义上讲 它本身
应该是无限地接近于O(1)的
所以这种算法
也是完全或者足以令我们满意的
-选课之前
--写在选课之前
--宣传片
-考核方式
--考核方式
-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)深度优先搜索--作业
-第六章 图--本章测验