当前课程知识点:数据结构(下) > 第七章 二叉搜索树 > (b1)BST:查找 > 07B1-5 查找:语义
最后我们再来考察这里的hot参数
作为一个引用型的参数
它总是在这个算法被首次调用时
统一地初始化为
初值为NULL的内部变量_hot
因此在随后算法的执行过程中
对这个参数的修改
实质上也就是对内部变量_hot的修改
我们可以看到 对_hot的修改
总是发生在每一次试图深入递归之前
具体来说 _hot会记下
此前刚刚接受访问的那个非空的节点
那么总体而言 _hot最终将会指向谁呢?
它所对应的语义又是什么呢?
为便于search接口更加简洁
也更加准确地被其它的算法使用
有必要对它的接口语义予以明确的定义
这体现在两个方面
首先这个接口的返回值在不同的情况下
分别对应于什么
其次经过这个算法的反复更新
hot变量的最终取值在各种情况下
又对应于什么
这些语义可以通过这个图来表示
实际上 也无非就是查找成功
以及查找失败 这两种情况
我们知道 返回值本身也是引用类型的
这里约定在查找成功时返回的引用
将指向一个真实存在的节点
而且这个节点恰好与目标关键码相等
而在查找失败时 返回的引用
将指向一个空节点
这里所说的空节点
是指首先它的数值为NULL
但正因为它是一个引用
更确切地讲
此时所返回的那个数值为NULL的引用
实际上就是我们在整个查找的过程中
最后一步所试图转入的
那个数值为空的分支
它指向查找路径末端节点
当前仍不存在的某一个孩子
而_hot呢 在查找成功时 它将指向
命中返回节点的父亲
而在失败的时候 它将指向
我们在整个查找过程中
最后访问的一个真实存在的节点
那么如何从语义上
将这两种情况下的返回值
以及_hot变量 统一起来呢?
一种简明的方法就是引入哨兵
是的 在查找失败的时候
我们可以在末端节点试图转向的
那个数值当前为空的引用处
增加一个假想的哨兵
而且可以进一步地假想着将它的关键码
就设置为我们查找的目标
当然不难验证 如果此时我们的确
在这个位置增加一个这样的真实的节点
那么全树依然将是一棵合法的BST
而更有意义的是
在引入了这样一个假想的哨兵之后
我们就可以从语义上
将两种情况统一起来
具体来说也就是
无论成功与否 我们的返回值
总是等效地指向命中节点
尽管在失败的情况下
这个命中的节点只是假想的
而非真实存在的
而在如此引入了一个假想的哨兵之后
_hot也可以认为总是指向
命中节点的父亲
那么基于这样一个语义明确的search接口
插入以及删除等算法
又当如何具体实现呢?
-选课之前
--写在选课之前
--宣传片
-考核方式
--考核方式
-OJ系统说明
--关于OJ
--1-注册与登录
--2-界面与选课
--3-提交测试
-关于课程教材与讲义
--课程教材与讲义
-关于讨论区
--关于讨论区
-微信平台
--html
-PA晋级申请
--PA晋级
-(a)概述
--07A-1 纵览
--07A-5 接口
-(a)概述--作业
-(b1)BST:查找
-第七章 二叉搜索树--(b1)BST:查找
-(b2)BST:插入
-(b2)BST:插入--作业
-(b3)BST:删除
-第七章 二叉搜索树--(b3)BST:删除
-(c)平衡与等价
-(c)平衡与等价--作业
-(d1)AVL树:重平衡
-第七章 二叉搜索树--(d1)AVL树:重平衡
-(d2)AVL树:插入
-(d2)AVL树:插入--作业
-(d3)AVL树:删除
-(d3)AVL树:删除--作业
-(d4)AVL树:(3+4)-重构
-(d4)AVL树:(3+4)-重构--作业
-本章测验
--章节测验
-(a1)伸展树:逐层伸展
--习题
-(a2)伸展树:双层伸展
--习题
-(a3)伸展树:算法实现
--习题
-(b1)B-树:动机
--习题
-(b2)B-树:结构
--习题
-(b3)B-树:查找
--习题
-(b4)B-树: 插入
--习题
-(b5)B-树: 删除
--习题
-(xa1)红黑树:动机
--习题
-(xa2)红黑树:结构
--习题
-(xa3)红黑树:插入
--习题
-(xa4)红黑树:删除
-本章测验
--习题
-(b)散列:原理
--09B-3 数组
--09B-4 原理
--09B-5 散列
--09B-6 冲突
--习题
-(c)散列:散列函数
--习题
-(d1)散列:排解冲突(1)
--习题
-(d2)散列:排解冲突(2)
--习题
-(e)桶/计数排序
--习题
-本章测验
--本章测试
-(a1)需求与动机
--习题
-(a2)基本实现
--习题
-(b1)完全二叉堆:结构
--习题
-(b2)完全二叉堆:插入与上滤
--习题
-(b3)完全二叉堆:删除与下滤
--习题
-(b4)完全二叉堆:批量建堆
--习题
-(c)堆排序
--习题
-(xa1)左式堆:结构
--习题
-(xa2)左式堆:合并
--习题
-(xa3)左式堆:插入与删除
-本章测验
--本章测试
-(a)ADT
--习题
-(b1)串匹配
--习题
-(b2)蛮力匹配
--习题
-(c1)KMP算法:从记忆力到预知力
--习题
-(c2)KMP算法:查询表
--习题
-(c3)KMP算法:理解next[]表
--习题
-(c4)KMP算法:构造next[]表
--习题
-(c5)KMP算法:分摊分析
--习题
-(c6)KMP算法:再改进
-(d1)BM_BC算法:以终为始
-(d2)BM_BC算法:坏字符
-(d3)BM_BC算法:构造bc[]
-(d4)BM_BC算法:性能分析
-(e1)BM_GS算法:好后缀
-(e2)BM_GS算法:构造gs表
-(e3)BM_GS算法:综合性能
-(f1)Karp-Rabin算法:串即是数
-(f2)Karp-Rabin算法:散列
-本章测验
--本章测试
-(a1)快速排序:算法A
-- 12a1-5: 实例
--习题
-(a2)快速排序:性能分析
--习题
-(a4)快速排序:变种
-(b1)选取:众数
-(b3)选取:通用算法
--习题
-(c1) 希尔排序:Shell序列
--习题
-(c2)希尔排序:逆序对
-本章测验
--本章测试