B树实现

B-树是一种平衡的多路查找树,它在文件系统中很有用。[1]

B-树主要用作文件的索引,因此它的查找涉及外存的存取。[1]

B-树适用于:当文件很大时,索引表(树表)本身也在外存,则查找索引时需多次访问外存,并且,访问外存的次数恰为查找路径上的结点数。为减少访问外存的次数,应尽量缩减索引表的深度。此时宜采用m叉的B-树作索引表。m的选择取决于索引项的多少和缓冲区的大小。[1]

 

实现语言:c++

1.B-树的查找

2.B-树的插入

 

#ifndef __BTREE_H
#define __BTREE_H

#include <iostream>
using namespace std;

typedef int KeyType;
#define M 3
typedef struct BTNode{
    int keynum;
    struct BTNode *parent;
    KeyType  key[M + 1];
    struct BTNode *ptr[M + 1];
}BTNode;

typedef struct Result{
    BTNode *pt;  //指向查找到的结点。
    int i;       //1..m,结点中的关键字标号
    int tag;     //1:查找成功。 0:查找失败
}Result;         //B-树查找结果类型

class BTree{
public:
    BTree();
    ~BTree();
    Result SearchBTree(KeyType k);
    void Insert(BTNode *p, int i, KeyType x, BTNode *ap);
    void split(BTNode *q, int s, BTNode **ap);
    void NewRoot(BTNode *q, KeyType x, BTNode *ap);
    int InsertBTree(KeyType K, BTNode *q, int i);
    int ShowBTNode(BTNode *p);
    int TraverseBTree(BTNode *p);
    BTNode * GetRoot();
private:
    BTNode *m_root;
};





#endif // __BTREE_H

 

#include "Btree.h"

BTree::BTree()
{
   m_root = NULL;
}

BTree::~BTree()
{
    delete m_root;
}

int Search(BTNode *p, KeyType K)
{
    int i = 1;

    for(i = 1; i <= p->keynum; ++i)
    {
        if(p->key[i] <= K)
        {
            if(i == p->keynum)
            {
                return i;
            }
            else if(p->key[i + 1] > K)
            {
                return i;
            }
        }else
        {
            return 0;
        }
    }
    return i;
}

Result BTree::SearchBTree(KeyType K)
{
    BTNode *p = m_root;
    BTNode *q = NULL;
    bool found = false;
    int i = 0;
    while((p != NULL) && !found)
    {
        i = Search(p, K);
        if((i > 0) && (p->key[i] == K))
        {
            found = true;
        }else
        {
            q = p; p = p->ptr[i];
        }
    }
    if(found) return {p, i, 1};
    else return {q, i, 0};
}
void BTree::Insert(BTNode *p, int i, KeyType x, BTNode *ap)
 {
     int j = p->keynum;
     for(;j >= i + 1; --j)
     {
         p->key[j + 1] = p->key[j];
         p->ptr[j + 1] = p->ptr[j];
     }
     p->key[i + 1] = x;
     p->ptr[i + 1] = ap;
     p->keynum++;
 }
 void BTree::split(BTNode *q, int s, BTNode **ap)
 {
     int i;
     *ap = new BTNode;
     (*ap)->parent = q->parent;
     (*ap)->keynum = M - s;
     (*ap)->ptr[0] = q->ptr[s];
     for(i = 1; i <= M - s; ++i)
     {
         (*ap)->key[i] = q->key[s + i];
         (*ap)->ptr[i] = q->ptr[s + i];
         if(q->ptr[s + i] != nullptr)
         {
             q->ptr[s + i]->parent = (*ap);
         }
      //   ap->recptr[i] = q->recptr[s + i];
     }
     q->keynum = s - 1;
 }

 void BTree::NewRoot(BTNode *q, KeyType x, BTNode *ap)
 {
        m_root = new BTNode;
        m_root->keynum = 1;
        m_root->key[1] = x;
        m_root->ptr[1] = ap;
        m_root->parent = NULL;
        m_root->ptr[0] = q;
        if(q != NULL)
        {
            q->parent = m_root;
        }
        if(ap != NULL)
        {
            ap->parent = m_root;
        }
 }

BTNode * BTree::GetRoot()
{
    return m_root;
}

int BTree::ShowBTNode(BTNode *p)
{
    int i = 1;
    for(; i <= p->keynum; ++i)
    {
        cout << i << ":" << p->key[i] << "| ";
    }
    cout << endl;
    return 1;
}

int BTree::TraverseBTree(BTNode *p)
{
    int i;
    if(p != NULL)
    {
        ShowBTNode(p);
        for(i = 0; i <= p->keynum; ++i)
        {
            TraverseBTree(p->ptr[i]);
        }
    }
    return 1;
}

int BTree::InsertBTree(KeyType K, BTNode *q, int i)
{
    KeyType x = K;
    BTNode *ap = NULL;
    bool finished = false;
    while((q != NULL) && !finished)
    {
        Insert(q, i, x, ap);
        if(q->keynum < M)
        {
          finished = true;
        }else
        {
            int s = M / 2 + 1;
            split(q, s, &ap);
            x = q->key[s];
            if(x == 70)
            {
                cout << "70" << q->parent->key[1] << endl;
            }
            q = q->parent;
            if(q != NULL)
            {
                i = Search(q, x);
            }
        }//else
    }//while
    if(!finished)
    {
        NewRoot(m_root, x, ap);
    }
    return 1;
}

 


#include "Btree.h"


int main()
{
    BTree bt;
    Result rs;
    rs = bt.SearchBTree(45);
    bt.InsertBTree(45, rs.pt, rs.i);
    rs = bt.SearchBTree(24);
    bt.InsertBTree(24, rs.pt, rs.i);
    rs = bt.SearchBTree(53);
    bt.InsertBTree(53, rs.pt, rs.i);
     rs = bt.SearchBTree(90);
    bt.InsertBTree(90, rs.pt, rs.i);
      rs = bt.SearchBTree(3);
    bt.InsertBTree(3, rs.pt, rs.i);
        rs = bt.SearchBTree(12);
    bt.InsertBTree(12, rs.pt, rs.i);
            rs = bt.SearchBTree(37);
    bt.InsertBTree(37, rs.pt, rs.i);
    rs = bt.SearchBTree(50);
    bt.InsertBTree(50, rs.pt, rs.i);
    rs = bt.SearchBTree(61);
    bt.InsertBTree(61, rs.pt, rs.i);
    rs = bt.SearchBTree(70);
   // cout << "kk" << rs.pt->key[1] << "  " <<  rs.i << endl;
    bt.InsertBTree(70, rs.pt, rs.i);
    rs = bt.SearchBTree(100);
    bt.InsertBTree(100, rs.pt, rs.i);
    bt.TraverseBTree(bt.GetRoot());
}

参考资料:

[1] 数据结构: C语言版/严蔚敏,吴伟民编著.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值