7.1 查找的基本概念
静态查找表: 无需插入和删除的查找表,反之称为 动态查找表
适合静态查找表的有:
- 顺序查找
- 折半查找
- 散列查找
适合动态查找表的有:
- 二叉排序树BST(包括进阶的平衡二叉树AVL、B树)
- 散列查找
关键字: 可以 唯一
标识元素的某个数据项的值
平均查找长度(查找算法效率的主要指标): 所有
查找过程中进行关键字比较次数的平均值:
A S L = ∑ i = 0 n P i C i ASL = \sum_{i=0}^{n} PiCi ASL=i=0∑nPiCi
Pi为概率
,如果所有元素概率相等,就是1 / n
Ci为比较次数
7.2.1 顺序查找(线性查找):
适用于顺序表、链表
1、一般线性表(无序):
如果概率相等时:
ASL成功 = (n+1)/ 2
ASL失败 = n + 1
顺序查找的:
- 优点:对存储没要求,顺序、链式都可以;对有序性也没要求
- 缺点:n较大时ASL比较大,效率低
注意: 对线性的链表,只能用顺序查找
2、有序表:
表的关键字有序,可以不用到表尾就能确定查找失败
如果概率相等时:
ASL成功 = 和无序一样
ASL失败 = n/2 + n/(n+1)
7.2.2 折半查找(二分查找):
仅使用于 有序的顺序表
二分查找判定树:平衡二叉树
ASL成功 = 从根结点到目标结点的路径上的结点数 = log2(n+1)-1
等概率情况下,计算:
ASL成功 = 根节点到所有圆形结点的路径的结点数求和 / n
ASL失败 = 根节点到方形结点(实际上不存在)的父节点的路径的结点数求和 / n
错题记录:
- 对表长为n的有序表进行折半查找,判定树的高度为: ⌈ l o g 2 ( n + 1 ) ⌉ \lceil log2(n+1) \rceil ⌈log2(n+1)⌉
- 具有12个关键字的有序表,概率相同,折半查找成功和失败的ASL分别多少?
答:因为有序,不妨设数为1~12,画出判定树,算ASL(注意要除以n) - [2017统考真题] 判断四个图那个能是二分查找判定树(不包括外部结点)
答:本质:二叉排序树中序是有序的。关键是判断向上还是向下取整,也就是左右子树的个数,向上取整,左子树就多
7.2.3 分块查找(索引顺序查找):
有顺序查找和折半查找的优点,既有动态结构,也适用于快速查找
思路:
- 将表分块,块内可以无序,但块间有序(例如第一个块中的都比第二个块中的小)
- 建立索引表,记录着每块的最大关键字和块中第一个元素的地址,索引表按关键字有序排列
步骤:
- 确定记录的块,可以顺序可以折半
- 块内顺序查找
错题记录:
- 对有2500个记录的索引顺序表(分块表)进行查找,理想的块长:
50
答:查找效率最高时,块长为记录数开根号
- 对65025个元素的有序顺序表进行分块查找,最好情况下的比较次数为:
16
答:效率最高时候,块长:65025开根号 = 255。然后索引和块内都用折半查找: ⌈ l o g 2 ( 255 + 1 ) ⌉ + ⌈ l o g 2 ( 255 + 1 ) ⌉ = 16 \lceil log2(255+1) \rceil + \lceil log2(255+1) \rceil = 16 ⌈log2(255+1)⌉+⌈log2(255+1)⌉=16
7.3.1 B树(多路平衡查找树):
B树是所有结点的平衡因子均等于0的多路平衡查找树
重点: 概念、建立、插入、删除
B树的阶:所有结点孩子个数最大值 m
m
阶B树(可为空)性质:
- 最多 有
m
棵子树,即结点中 最多m-1
个关键字 - 根结点若不是终端结点,最少 有
2
棵子树 - 根结点外的所有非叶结点 至少 有 ⌈ m / 2 ⌉ \lceil m/2 \rceil ⌈m/2⌉个子树,即 ⌈ m / 2 ⌉ − 1 \lceil m/2 \rceil - 1 ⌈m/2⌉−1个关键字
- 非叶节点由
指向子树的指针
和关键字
(关键字为指向子树根结点的指针
)交替组成,且有从小到大的大小关系 - 所有叶节点(外部结点)都在同一层,且不带信息,类似于折半查找树的 失败结点
B树的查找
类似于二叉搜索树
每个结点都是多关键字的有序表
- B树中找结点 (磁盘)
- 结点内找关键字 (内存)
找到目标结点后,结点信息读入内存,再在结点内采用顺序或折半
B树操作所需的磁盘存取次数
和B树的高度
成正比
B树的插入:
插入时,如果导致结点关键字数大于m-1
就会分裂,如果还过多继续往上分裂,如果根结点也分裂了,树高+1
当关键字多于
⌈
m
/
2
⌉
\lceil m/2 \rceil
⌈m/2⌉ - 1时,从中间位置分开,中间位置的关键字加入父节点
B树的删除:
删除时,如果导致结点关键字数小于 ⌈ m / 2 ⌉ − 1 \lceil m/2 \rceil - 1 ⌈m/2⌉−1 ,则需要它和兄弟结点合并成一个结点
7.3.2 B+树:
B+树时应文件系统要求产生,适用于操作系统的文件索引和数据库索引
- 每个分支结点最多有m棵子树
- 非叶根结点至少有m棵子树,其他分支结点至少有 ⌈ m / 2 ⌉ \lceil m/2 \rceil ⌈m/2⌉ 棵子树
- 子树的个数和关键字数相等
- 所有叶结点包含全部关键字及指向对应
记录
的指针,叶结点按关键字大小排序,相邻叶结点也按大小顺序链接 - 所有分支结点仅仅包含他的子结点中关键字的最大值及对应的指针
补充:
B+树有两个头指针,对应两种查找:
- 指向根节点——根节点开始的多路查找
- 指向关键字最小的叶节点——最小关键字开始的顺序查找
B+树的查找一定是查到叶结点为止
,不论是否成功,每次查找都是从根结点到叶结点
补充:B树和B+树的差异:
错题记录:
-
B树中,非终端结点的子树范围: ⌈ m / 2 ⌉ \lceil m/2 \rceil ⌈m/2⌉~ m,根节点:2 ~ m
-
有
n
个关键字的m阶B树有n+1
个叶结点,因为叶结点对应失败的情况 -
h = 5, m = 3的B树至少有
31
个结点,最多有121
个结点
解释:最少结点情况: 此时根节点和其余结点均取最少的情况,也就时都是2棵子树,此时类似于一棵满二叉树, 25-1 = 31个结点;最多结点情况: 此时根节点和其余结点都取m棵子树,此时类似于一颗满三叉树, (35 - 1)/ 2 = 121个结点 -
h = 2, m = 5的B树至少有
5
个结点
解释,当根节点的关键字超过m-1时,就分裂,h变成2
注意:m
阶B树并不一定要出现有m-1
个关键字的结点 -
h = 5, m = 3的B树含关键字最少为:
31
根节点至少含1个关键字,其余非叶结点最少含 ⌈ m / 2 ⌉ \lceil m/2 \rceil ⌈m/2⌉ - 1 = 1个关键字,因此最少情况为h = 5的满二叉树:25 - 1 -
含有n个非叶结点的m阶B树中至少包含多少个关键字?
首先根节点最少1个关键字,其余n-1个结点,每个结点最少( ⌈ m / 2 ⌉ \lceil m/2 \rceil ⌈m/2⌉ - 1)个关键字