当前课程知识点:数据结构(上) > 第二章 向量(下) > (d3)有序向量:Fibonacci查找 > 02D3-4 最优性
其实我们也已经能够发现
无论是binary search
还是fibonaccian search
它的模式其实都是大同小异的
概括而言,它们都属于一类算法的模式
具体来讲,这种模式表现为,在每一次
试图减而治之的时候
我们所选取的那个切分点
也就是轴点的不同
一般而言
对于一个长度为N的有序向量
我们采取的策略,实际上是
决定于某一个在0与1之间的常数λ
也就是说,一旦这样的一个λ确定以后
每次我们都是以λn作为我们的轴点
比如说,对于binary search而言
这个λ取的其实就是0.5
而对于fibonaccian search而言
取的数恰好是小写的φ
也就是这个很神秘的黄金分割比例
可以说,每一个λ其实都对应着一个算法
那么λ取什么样的一个数值的时候
才能使得这个算法的性能达到整体的最优呢?
在这里而言,其实也就是平均查找长度
达到最小
所谓的最优,其实就是最小
如果我们这里的查找长度
从渐近地意义上讲
依然可以度量为一个logn
那么实际上,这里所考量的更重要的是
它对应的那个常系数
这个系数是取决于λ选取的
所以我们不妨把它
记作是一个函数 α(λ)
所以我们的问题,归结一下就是
在[0,1]之间取一个什么样的λ的时候
能够使得α(λ)达到最小
我们可以得到这样一个递推式
我们来理解一下
这个递推式的左右
实际上算的都是同一个东西
所以它可以用等号连起来
是什么呢?
其实就是对于最初的这个向量而言
平均查找长度是多少
它的左侧是一个简便的记法
其实就是我们刚才所定义的那个
以logn为渐近复杂度
然后配上一个系数
而右侧呢
分为左右的两部分
是一个总和
哪两部分呢?
其实分别的对应的就是
我们向左侧深入
以及向右侧深入的情况
不同的在于,我们要用它们的概率
来做一个加权平均
它们的概率,如果假设所有的元素
出现的概率都是一样的话
那么每一个区段所进入的概率
其实就等于它的区段的长度
具体来说一个是λ
一个是λ-1(注:应该是1-λ)
好,递推下去
对于左侧的这个长度为λn的这个序列而言
它所对应的平均查找长度,当然是这个了
对应右边那个长度为1-λ
再乘以n的这个序列而言
它的平均查找长度,当然也就是这个了
那么不要忘了
在我们这里
在目前的这种实现机制下
对于原来这个序列
如果要做切分
那么如果某一个方向
可以做到一次比较就够了的话
那么另一个方向必然需要两次
当然可能对称过来
所以这里我们不要忘了
还要把这里的成本
就是进入左侧的这个成本1加上
再把进入右侧的这个成本2再加上
经过整体的这样一个解释之后
我们就应该说
这个递推式的确是成立的
接下来的呢
接下来的事情就要相对简单一些了
因为它只需要运用
高等数学的一些基础的知识
比如一种方法是
我们可以对这个递推式进行整理
得到这么样一个等式
接下来
只要运用求极值的一些常规方法
不难证明,非常巧
恰好这个λ,在选作为黄金分割比
也就是小写的φ的时候
这个α(λ)达到最小
而且这个最小值
确切地讲,就是1.44左右
相对于我们上一节所介绍的二分查找
1.50这样一个常系数
又有了一定的改进
而且从我们这一页的分析可以看出
这种改进已经达到了极限
如果我们不再改变
这个算法的总体模式和框架的话
-选课之前
--写在选课之前
--宣传片
-考核方式
--考核方式
-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)深度优先搜索--作业
-第六章 图--本章测验