当程序提出大小为n的内存分配请求时,首先在可利用表中查找大小与n相匹配的子表.
◆ 若存在2^(k-1)< n ≤ 2^k-1的空闲子表结点:则将子表中的任意一个结点分配之;
◆ 若不存在2^(k-1) < n ≤ 2^k-1的空闲子表结点:则从结点大小为2^k的子表中找到一个空闲结点,将其中一半分配给程序,剩余的一半插入到结点大小为2k-1的子表中。
注:在进行大小为n(2^(k-i-1) < n ≤ 2^(k-i)-1,i=1,2,…,k-1) 的内存分配请求时,若所有小于2^k的子表均为空(没有空闲结点),则同样需要从大小为2^k的子表中找到一个空闲结点,将其中2^(k-i)一小部分分配给用户,而将剩余部分分割成若干个结点分别插入对应的子表。
当程序释放所占用的块时,系统将该新的空闲块插入到可利用空闲表中,需要考虑合并成大块问题。在伙伴系统中,只有“互为伙伴”的两个子块均空闲时才合并;即使有两个相邻且大小相同的空闲块,如果不是“互为伙伴” (从同一个大块中分裂出来的)也不合并。
设深度为h的平衡二叉排序树所具有的最少结点数为Nh,则由平衡二叉排序树的性质知:
N0=0,N1=1,N2=2,… ,Nh= Nh-1+Nh-2
平衡二叉排序树便于动态查找,因此用平衡二叉排序树来组织索引表是一种可行的选择。当用于大型数据库时,所有数据及索引都存储在外存,因此,涉及到内、外存之间频繁的数据交换,这种交换速度的快慢成为制约动态查找的瓶颈。若以二叉树的结点作为内、外存之间数据交换单位,则查找给定关键字时对磁盘平均进行㏒2n次访问是不能容忍的,因此,必须选择一种能尽可能降低磁盘I/O次数的索引组织方式。树结点的大小尽可能地接近页的大小。
B_树主要用于文件系统中,在B_树中,每个结点的大小为一个磁盘页,结点中所包含的关键字及其孩子的数目取决于页的大小。一棵度为m的B_树称为m阶B_树
一棵m阶B_树,或者是空树,或者是满足以下性质的m叉树:
⑴ 根结点或者是叶子,或者至少有两棵子树,至多有m棵子树;
⑵ 除根结点外,所有非终端结点至少有m/2【向上取整】棵子树,至多有m棵子树;
⑶ 所有叶子结点都在树的同一层上;
设n是结点中关键字的个数,且m/2【取下限】-1≤n≤m-1,n+1为子树的棵数。
在实际的文件系统中,基本上不使用B_树,而是使用B_树的一种变体,称为m阶B+树。 它与B_树的主要不同是叶子结点中存储记录。在B+树中,所有的非叶子结点可以看成是索引,而其中的关键字是作为“分界关键字”,用来界定某一关键字的记录所在的子树。一棵m阶B+树与m阶B_树的主要差异是:
⑴ 若一个结点有n棵子树,则必含有n个关键字;
⑵ 所有叶子结点中包含了全部记录的关键字信息以及这些关键字记录的指针,而且叶子结点按关键字的大小从小到大顺序链接;
⑶ 所有的非叶子结点可以看成是索引的部分,结点中只含有其子树的根结点中的最大(或最小)关键字。
与B_树相比,对B+树不仅可以从根结点开始按关键字随机查找,而且可以从最小关键字起,按叶子结点的链接顺序进行顺序查找。在B+树上进行随机查找、插入、删除的过程基本上和B_树类似。
在B+树上进行随机查找时,若非叶子结点的关键字等于给定的K值,并不终止,而是继续向下直到叶子结点(只有叶子结点才存储记录) , 即无论查找成功与否,都走了一条从根结点到叶子结点的路径。
B+树的插入仅仅在叶子结点上进行。当叶子结点中的关键字个数大于m时,“分裂”为两个结点,两个结点中所含有的关键字个数分别是(m+1)/2【取下限】和 (m+1)/2【取上限】 ,且将这两个结点中的最大关键字提升到父结点中,用来替代原结点在父结点中所对应的关键字。提升后父结点又可能会分裂,依次类推。
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文地址:http://blog.csdn.net/barry283049/article/details/48111103