《数据结构、算法与应用 —— C++语言描述》学习笔记 — 平衡搜索树 — B树
一、索引顺序访问方法
当字典足够小,可以整个驻留在内存中时,AVL树和红黑树都能够保证良好的时间性能。对于那些必须存储在磁盘上的大型字典(外部字典或文件),需要度数更高的搜索树来改善字典操作的性能。我们先学习以下外部字典的索引访问顺序方法(ISAM)。
在ISAM中,可用的磁盘空间被划分为很多块。块是在磁盘空间中用来输入或输出的最小单位。块一般具有和磁道一样的长度,而且可以在一次搜索和延迟中完成输入或输出。字典元素以升序存储在块中。而且这些块,使得从一块到另一块的延时最短按照一种顺序来组织。
在顺序访问时,块按序输入,每一个块中的元素按升序搜索。如果每个块包含 m 个元素,则搜索每个元素所需要的磁盘访问次数为 1/m。
要支持随机访问,就要维持一个索引。索引包括每个块的最大关键字。这样一来,索引中的关键字数量与块的数量相同,并且每个块都能存储很多元素(即 m 值较大),因此索引足以整个驻留内存中。为了随机访问关键字为 k 的元素,首先要查找索引表,确定该元素所属的块,然后把相应的块从磁盘中取出进行内部搜索,以确定该元素。结果一次磁盘访问就足以完成一次随机访问。
这种技术可以扩充到更大的字典,这种字典存储在若干个磁盘。这时的元素按升序被分配到不停地磁盘中,在一个磁盘中的元素又按升序被分配到不同块中。每个磁盘都有一个块索引,它保存着在该磁盘中每个块的最大关键字。另外,还有一个磁盘索引,它保存着每个磁盘的最大关键字。磁盘索引一般驻留在内存中。
为了随机访问一个元素,首先要搜索驻留在内存中的磁盘索引,以确定该元素所属的磁盘;然后从该磁盘中取出块索引进行搜索,以确定该元素所属的块;最后从磁盘中取出块进行内部搜索,以确定该元素。这样一来,一次随机访问需要两次磁盘访问。
ISAM 方法本质上是一种数组描述方法。因此,当执行插入和删除时,会面临很大问题。为了部分地环节问题的压力,可以在每个块中预留一些空间,使得在插入少量元素时,不需要在块与块之间移动元素。
使用 ISAM 方法可以解决这些难题,但是顺序访问的代价提高了。以任意顺序存储的元素,每一个关键字的索引都要检查,所有元素都通过这个索引来访问。对存储在磁盘上的数据,B树是一种适合于索引方法的数据结构。
二、m叉搜索树
1、定义
m叉搜索树可以是一棵空树。如果非空,它必须满足以下特征:
① 在相应的扩充搜索树中(即用外部节点替换空指针之后所得到的搜索树),每个内部节点最多可以有 m 个孩子以及 1 ~ m - 1 个元素(外部节点不含元素和孩子)。
② 每一个含有 p 个元素的节点都有 p+1 个孩子。
③ 对任意一个含有 p 个元素的节点,设 k 1 k_1 k1, k 2 k_2 k2,···, k p k_p kp分别是这些元素的关键字。这些元素顺序排列,即 k 1 < k 2 ⋅ ⋅ ⋅ < k p k_1 < k_2 ··· < k_p k1<k2⋅⋅⋅<kp。设 c 0 c_0 c0, c 1 c_1 c1,···, c p c_p cp分别是该节点的 p + 1 个孩子。在以 c 0 c_0 c0为根的子树中,元素的关键字小于 k 1 k_1 k1,在以 c p c_p cp为根的子树中,元素的关键字大于 k p k_p kp;在以 c i c_i ci为根的子树中,元素的关键字大于 k i k_i ki