当前课程知识点:数据结构(上) > 第二章 向量(上) > (d2)有序向量:二分查找 > 02D2-3 语义
这种在语义上进一步地细致约定
是非常有必要的
否则的话,我们的search接口
将只能作为一个孤立的功能
而不能有效地、便捷地
为其它的算法,作为一个基本的部件而利用
比如说,search接口至少应该
使得有序向量自身的动态维护变得非常便利
比如说,在有序向量不断插入元素过程中
我们希望往往能够采用这样一种形式
也就是说,当我们需要
去插入某一个元素的时候
我们首先要通过search
来确定一个适当的位置
比如说,就是这个查找返回的那个值再加1
然后再将e插入于这样一个秩所对应位置
并且同时使得这个有序向量
继续是一个有序向量
所以这样的话
对我们刚才所说的几种特殊情况
就有明确的要求
而不是说可以简单地处理
比如说,即便是失败
我们也需要给出新元素插入的适当的位置
也就是说,我即使跌倒了,我也不能白白跌倒
我应该为后继者提供一个参考的依据
反过来,即便是有重复的元素
比如说像刚才所说的
在这个地方,可能有多个元素
构成一个区段
它们都是某一个特定的元素
我也需要使得新插入的元素
总是,比如说,排在最后或者是排在最前
这样的话呢
能够使得每一组这样的元素
排列的相对次序
与它们的插入的次序是吻合的
那么这些呢,都是属于语义方面的
更深入的要求
很幸运,前人已经帮我们设计出了
这样的语义约定
比如说,这就是其中的一种
我们这里约定
search接口的返回值总可以概括地
说是不大于目标的最后那个元素
确切地讲,是它的秩
我们来看几种特殊的情况
第一种情况,就是查找失败
如果查找失败,按照这里的约定
它会失败在
一个不大于这个e的最大的那个元素
所以如果随后的这个元素是存在的
它必然是大于e的
而这边这个呢,必然是小于等于e的
所以如果返回值是在这
我们将新的那个元素插入在
它的位置再加1的这个位置上
那么是再合适不过的了
其实这里头也有几种特殊的情况
比如说,这个元素确实不存在
但是它的数值非常非常的小
以致于这个区间内,最左侧最小的这个元素lo
也比它大
这个时候有效范围内的任何元素
都是不能作为返回值返回的
这时候我们返回什么呢?
我们倾向于返回lo-1
因为这样的话
如果我们接下来确实要把这个元素插入进来
那么也就是插入在lo这个位置上
这个和我们的要求是吻合的
那么怎么做到这一点呢?
我们说,以假想地在lo的左侧
就像现在这样,再增加一个哨兵
而它的数值呢
我们可以等效地认为,是等于负无穷
反过来,如果
待插入的这个元素e非常非常大
以致于连实际存在的这个
最大的这个hi-1也要比它严格地小
那么这个时候呢
如果要插入的话,应该插入在hi这个位置
这个虚拟的
有可能根本不存在的这样的一个位置上
那么这个时候
返回的值应该是hi-1
再合适不过了
因为如果是hi-1是作为返回值的话
那么把这个数值插在hi这个位置上
和我们的功能也是吻合的
所以对称地
我们不妨认为这个假想的哨兵hi
所具有的数值也是有的
只不过它是正无穷
所以这种情况不仅能处理
而且可以有一个很好的一个解释
再来看,重复元素的情况
如果确实像刚才所言,在这个地方
可能有多个元素是与目标的元素是重复的
这个时候呢
我们说这个算法按照这里的要求
应该返回的所谓的不大于e的最后一个元素
当然也就是这个区段的右端点了
所以接下来,如果我们要做一个插入
也就是说
把这个位置同样地加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)深度优先搜索--作业
-第六章 图--本章测验