📜  数据结构-B Tree(1)

📅  最后修改于: 2023-12-03 14:54:56.442000             🧑  作者: Mango

数据结构 - B Tree

简介

B Tree是一种多路平衡搜索树,常用于磁盘和数据库系统等常见的外存储器系统中,能够显著减少磁盘I/O读写操作,提高效率。

一个B Tree可以看做是一个平衡的二叉树,但其每个非叶节点可以拥有更多的子节点,一般称为“度”。比如,2-3 B Tree,其中每个非叶节点最多可以有2个或3个子节点,对应2-3度(degree)。

组成

B Tree有以下几个组成部分:

  • 根节点:最上层的节点。如果搜索树非空,则根节点必须至少包含一个键。
  • 内部节点:非根节点。它们包含至少一个键和指针,每个指针都指向另一个B Tree结构(可能是叶节点,也可能是内部节点)。
  • 页(即叶节点):树的最底层。它们包含至少一个键和指针,每个指针都指向一个搜索单元(记录或者数据块)。
  • 键(key):节点存储的单个值,作为在B Tree中的搜索依据。
  • 指针:指向叶节点或其它B Tree部分的引用。
  • 搜索单元:外存储器中的物理块或磁盘上的数据记录。
插入操作

B Tree的插入操作分为以下几个步骤:

  1. 沿根到叶子的路径寻找插入键的位置。
  2. 如果找到了对应的键,则覆盖其中的值。
  3. 如果所在叶子未满,插入键。
  4. 如果所在的叶子已满,分裂并重组。
  5. 如果分裂导致父节点也满了,重复上面步骤。

B Tree中的插入操作能够尽量把数据均匀地分配到各个子树中,这使得B Tree成为了数据库索引中常用的数据结构。

删除操作

B Tree的删除操作比插入操作更加复杂。通常需要对节点的删除进行后继继承或者前驱继承。同时,删除操作能够保证B Tree保持平衡。

代码实现

以下是B Tree的C++代码实现,用于向B Tree中插入数据。

struct BTreeNode 
{ 
    int *keys;      
    int t;          
    BTreeNode **C;  
    int n;         
    bool leaf;     
}; 
  
BTreeNode *createNode(int t, bool leaf) 
{ 
    BTreeNode *newNode = new BTreeNode; 
    newNode->t = t; 
    newNode->leaf = leaf; 
    newNode->keys = new int[2*t-1]; 
    newNode->C = new BTreeNode *[2*t]; 
    newNode->n = 0; 
    return newNode; 
} 
  

void insertNonFull(BTreeNode *root, int k) 
{ 

    int i = root->n-1; 
  
    if (root->leaf == true) 
    {  
        while (i >= 0 && root->keys[i] > k) 
        { 
            root->keys[i+1] = root->keys[i]; 
            i--; 
        } 

        root->keys[i+1] = k; 
        root->n = root->n+1; 
    } 
    else   
    { 
        while (i >= 0 && root->keys[i] > k) 
            i--; 

        if (root->C[i+1]->n == 2*root->t-1) 
        { 
            splitChild(root, i+1, root->C[i+1]); 
  
            if (root->keys[i+1] < k) 
                i++; 
        } 
        insertNonFull(root->C[i+1], k); 
    } 
} 
  
void insert(BTreeNode *&root, int k) 
{ 

    if (root == NULL) 
    { 

        root = createNode(t, true); 
        root->keys[0] = k; 
        root->n = 1;  
    } 
    else 
    { 

        if (root->n == 2*t-1) 
        { 

            BTreeNode *s = createNode(t, false); 
  
            s->C[0] = root; 
  
            splitChild(s, 0, root); 

            int i = 0; 
            if (s->keys[0] < k) 
                i++; 
            insertNonFull(s->C[i], k); 
  
            root = s; 
        } 
        else 
            insertNonFull(root, k); 
    } 
}