前言:
有段时间在研究T树算法,在网上只找到一篇,借鉴了一下,但是原博客中的代码出现了大量的错误,所以自己
按照原博客的思想与大部分代码重新推算演练了一下,因为站在巨人的肩膀上,所以整理的容易了一些,但是毕竟努力了很长时间,所以发篇博客吧。
一、原理与思想
磁盘数据库系统的典型的索引技术是B-tree索引。B-tree结构的主要目的是减少完成数据文件的索引查找所需要
的磁盘I/O的数量。B-tree通过控制节点内部的索引值达到这个目的,在节点中包含尽可能多的索引条目(增加一次
磁盘I/O可以访问的索引条目)。T-Tree是针对主存访问优化的索引技术。T-tree是一种一个节点中包含多个索引条
目的平衡二叉树,T-tree的索引项无论是从大小还是算法上都比B-tree精简得多。T-tree的搜索算法不分搜索的值
在当前的节点还是在内存中的其他地方,每访问到一个新的索引节点,索引的范围减少一半。
T树索引用来实现关键字的范围查询。T树是一棵特殊平衡的二叉树(AVL),它的每个节点存储了按键值排序的一
组关键字。T树除了较高的节点空间占有率,遍历一棵树的查找算法在复杂程度和执行时间上也占有优势。T树节点结
构如图所示。
T-Tree具有以下特点:
(1)T-Tree中有平衡点balance,balance=右子树的深度-左子树的深度,balance的绝对值小于等于1,也就是说T-Tree
是一颗和平衡二叉树相似的树。如果插入节点,导致balance绝对值大于1,需要经行旋转来平衡树。
(2)T-Tree中的节点可以存储n个数据,n=存储上限。在上面的节点结构图中,K1最小,Kn最大。
(3)为了保证每个节点的空间利用率,每个节点中存储的数据个数必须大于等于存储下限,一般存储下限=存储上限-2。
(4)T-Tree节点的左子节点中存储的数据要小于当前节点中的最小数据K1,T-Tree节点的右子节点中存储的数据要
大于当前结点中的最大数据Kn。
(5)同时拥有左右子树的节点被称为内部节点,只拥有一个子树的节点被称为半叶一,没有子树的节点被称为叶子。
二、操作算法
程序中定义的节点结构如下:
typedef struct TTREENODE //树节点的结构
{
TTREENODE *left; //节点的左子树指针
TTREENODE *right; //节点的右子树指针
unsigned short int nItems; //节点中键值的数目
ElementKey key[ttPageSize]; //key值数组
ElementData data[ttPageSize]; //对应数据行的指针数组
int balance; //balance(平衡因子),其绝对值不大于1,balance =右子树高度-左子树高度;
} TTREENODE;
1、查找算法
根据给予的key值,查找对应的data值。从根节点开始,把key值分别与当前结点的最小key值key[0]和
最大key值key[nItems-1]比较:如果key值小于当前结点的最小key值,则把key值与当前节点的左子树节点中的数据
进行比较;如果key值大于当前结点的最大key值,则把key值与当前结点的右子树节点中的数据进行比较;
如果不符合上述情况,则证明key值就在当前结点数组的范围内,采用二分查找在节点key值数组中找到与key值相等
位置,然后返回data数组中对应位置的数据即可。其他情况则是查找失败,返回NULL;
伪码描述:
算法:T-Tree FindRecord
输入:key值
输出:data值
步骤:
1,定义一个节点pNode =根节点root;
2,while(pNode!=NULL)
3,{
4