一棵M阶(M>2)的B树,是一棵平衡的M路平衡搜索树,可以是空树或者满足一下性质:

1. 根节点至少有两个孩子

2. 每个非根节点有[ ,M]个孩子

3. 每个非根节点有[ -1,M-1]个关键字,并且以升序排列

4. key[i]和key[i+1]之间的孩子节点的值介于key[i]、key[i+1]之间

5. 所有的叶子节点都在同一层

ps: 是向上取整

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
#pragma once
template<class K, int M = 3>
struct BTreeNode
{
    K _keys[M];                    // 关键字数组
    BTreeNode<K, M>* _subs[M + 1];    // 孩子数组
    size_t _size;              // 关键字的个数
    BTreeNode<K, M>* _parent;   // 父亲
    BTreeNode()
        :_size(0)
        , _parent(NULL)
    {
        for (size_t i = 0; i < M + 1; ++i)
        {
            _subs[i] = NULL;
        }
    }
};
template<class K, class V>
struct Pair
{
    K _first;
    V _second;
    Pair(const K& k = K(), const V& v = V())
        :_first(k)
        , _second(v)
    {}
};
template<class K, int M = 3>
class BTree
{
    typedef BTreeNode<K, M> Node;
public:
    BTree()
        :_root(NULL)
    {}
    Pair<Node*, int> Find(const K& key)
    {
        Node* parent = NULL;
        Node* cur = _root;
        while (cur)
        {
            int i = 0;
            while (i < cur->_size && cur->_keys[i] < key)
            {
                ++i;
            }
            if (cur->_keys[i] == key)
            {
                return Pair<Node*, int>(cur, i);
            }
            parent = cur;
            cur = cur->_subs[i];
        }
        return Pair<Node*, int>(parent, -1);
    }
    bool Insert(const K& key)
    {
        if (_root == NULL)
        {
            _root = new Node;
            _root->_keys[0] = key;
            ++_root->_size;
            return true;
        }
        Pair<Node*, int> ret = Find(key);
        if (ret._second != -1)
        {
            return false;
        }
        K k = key;
        Node* cur = ret._first;
        Node* sub = NULL;
        // 在cur节点插入一个k
        while (1)
        {
            _InsertKey(cur, k, sub);
            if (cur->_size < M)
            {
                return true;
            }
            // 分裂
            int boundary = M / 2;
            Node* tmp = new Node;
            size_t index = 0;
            size_t size = cur->_size;
            // 拷贝key
            for (int i = boundary + 1; i < size; ++i)
            {
                tmp->_keys[index++] = cur->_keys[i];
                tmp->_size++;
                cur->_size--;
            }
            // 拷贝子节点
            index = 0;
            for (int i = boundary + 1; i <= size; ++i)
            {
                tmp->_subs[index] = cur->_subs[i];
                if (tmp->_subs[index])
                    tmp->_subs[index]->_parent = tmp;
                ++index;
            }
            k = cur->_keys[boundary];
            cur->_size--;
            // 没有父亲
            if (cur->_parent == NULL)
            {
                _root = new Node;
                _root->_keys[0] = k;
                _root->_subs[0] = cur;
                _root->_subs[1] = tmp;
                _root->_size = 1;
                tmp->_parent = _root;
                cur->_parent = _root;
                return true;
            }
            cur = cur->_parent;
            sub = tmp;
        }
    }
    void _InsertKey(Node* cur, const K& k, Node* sub)
    {
        int i = cur->_size - 1;
        while (i >= 0)
        {
            if (cur->_keys[i] > k)
            {
                cur->_keys[i + 1] = cur->_keys[i];
                cur->_subs[i + 2] = cur->_subs[i + 1];
                --i;
            }
            else
            {
                break;
            }
        }
        cur->_keys[i + 1] = k;
        cur->_subs[i + 2] = sub;
        if (sub)
        {
            sub->_parent = cur;
        }
        cur->_size++;
    }
    void InOrder()
    {
        _InOrder(_root);
        cout << endl;
    }
    void _InOrder(Node* root)
    {
        if (root == NULL)
        {
            return;
        }
        for (size_t i = 0; i < root->_size; ++i)
        {
            _InOrder(root->_subs[i]);
            cout << root->_keys[i] << " ";
        }
        _InOrder(root->_subs[root->_size]);
    }
protected:
    Node* _root;
};
void TestBTree1()
{
    BTree<int, 1024> t1;
    int a[] = { 53, 75, 139, 49, 145, 36, 101 };
    for (int i = 0; i < sizeof(a) / sizeof(a[0]); ++i)
    {
        t1.Insert(a[i]);
    }
    t1.InOrder();
}

本文转自 七十七快 51CTO博客,原文链接:http://blog.51cto.com/10324228/1771019

Btree(B-树)---C++相关推荐

  1. ORACLE B-TREE(B树)索引

    内容简介: 1.普通B-TREE 索引; 2.唯一B-TREE 索引; 3.复合索引; ORACLE 默认的索引类型为B-TREE 索引,表中的行标识符(ROWID)和行相关的列值被存储在一个平衡树的 ...

  2. b树c语言,B树——思路、及C语言代码的实现

    合并: 在此先声明,因为一开始只考虑B树的阶为4的情况,后来改为使用宏定义阶M的数值,所以这段代码存在BUG,只支持阶为3或4的B树= =. 思路还是挺清晰的,首先先向兄弟结点借元素,如果兄弟能够借给 ...

  3. mysql rtree_优化体系--MySQL 索引优化(full-text、btree、hash、rtree)

    概述 目前大部分数据库系统及文件系统都采用B-Tree(B树)或其变种B Tree(B 树)作为索引结构.B Tree是数据库系统实现索引的首选数据结构.在MySQL中,索引属于存储引擎级别的概念,不 ...

  4. b - 数据结构实验之查找二:平衡二叉树_二叉树、平衡二叉树、红黑树、B树、B+树与B*树...

    一.二叉树 1️⃣二叉查找树的特点就是左子树的节点值比父亲节点小,而右子树的节点值比父亲节点大,如图: 基于二叉查找树的这种特点,在查找某个节点的时候,可以采取类似于二分查找的思想,快速找到某个节点. ...

  5. 基于B树的图书管理系统(C语言)(含完整代码)

    目录: 一.实现的设计要求 1.基本要求 2.额外选做要求 二.项目文件管理 三.完整代码 1.实现的接口 2.头文件 BTreeBook.h 全部代码 3.源文件 BTreeBook.cpp 全部代 ...

  6. MySQL的存储引擎InnoDB选择了B+ 树

    我们知道数据的存储和检索是两个很重要的功能,当我们的数据量大了,怎么能快速的检索数据呢,答案是使用索引,可索引具体的技术实现有很多,选择哪一种呢,我就以mysql为例记录下它为什么选择了B+树作为索引 ...

  7. 超级详细树讲解三 —— B树、B+树图解+代码

    首先很高兴你看到了这篇文章,这篇文章可能会花费你很长很长的时间去看,但是这篇文章包括的内容绝对足够你对树的一个系统性的学习.为什么要写这篇文字呢?因为自己在学习树的时候,有些博客只有图解,有些博客只有 ...

  8. 大白话btree和b+tree

    引语 作为一直后端程序猿,经常会看到好几个关于树的概念,平衡二叉树,二叉搜索树,avl树,btree,b+tree等等.没有弄清楚的时候,放到一起很容易弄混.今天咱们就来捣鼓捣鼓这几个名词,理解一下它 ...

  9. 数据结构课设--用B树实现图书管理系统

    此文章是分享一下上学期数据结构课程的课程设计,我选择的是以B树为数据结构,开发一个图书管理系统,B树的优点在于查询快,增删结点相对于链表或者顺序表效率更好,因此用来存储大量图书信息更加合适.(开发环境 ...

  10. MySQL 简单了解B+树

    目录 前言 一.二叉树 1.特殊类型 ⑴.满二叉树 ⑵.完全二叉树 2.什么是二叉查找树? ⑴.二分查找算法 ⑵.二叉查找树(BST) 3.自平衡二叉查找树 ⑴.平衡二叉树(AVL) ⑵.红黑树 ⑶. ...

最新文章

  1. 他211本硕毕业,一边是年薪15万国企送北京户口,一边是28万大厂offer,究竟该怎么选?...
  2. mysql python 接口_Python中的MySQL接口:PyMySQL MySQLdb
  3. 虚拟化--046 利用web client查看存储
  4. python爬虫1——获取网站源代码(豆瓣图书top250信息)
  5. ML:MLOps系列讲解之系列知识解读全貌
  6. 【线性规划与网络流24题】孤岛营救问题 分层图
  7. 文曲星猜数游戏的非TDD实现
  8. 微信小程序原生 地区选择器
  9. 共享内存简介及docker容器的shm设置与修改
  10. [渝粤教育] 西南科技大学 机械制造装备及工艺 在线考试复习资料(1)
  11. 今天我点亮了CSDN博客专家殊荣
  12. 好书推荐_Windows程序设计(第五版)
  13. android游戏菜鸟教程,菜鸟教程app
  14. OFDM子载波正交特性matlab,OFDM的正交性(转)
  15. win7系统调整屏幕刷新率方法
  16. 仿小米商城SpringBoot+Vue全栈项目开发实战文档
  17. wps自动插入文献_WPS中怎样自动生成参考文献?方法超级简单!
  18. 2020年iOS如何申请苹果公司开发者账号流程详细图文介绍
  19. 不能爬小程序,叫什么会爬虫
  20. 使用Enounce MySpeed对flv加速播放

热门文章

  1. 不再受限于数据集和硬件,下一代 ML 软件如何构建?
  2. 「NLP」ALBERT:更轻更快的NLP预训练模型
  3. 商业大佬提醒:如果不采取措施,美国在人工智能领域将落后于中国
  4. 2017回顾与2018前瞻:机器学习与人工智能
  5. pip 或者conda 下载安装torch-{cluster,geometric,scatter,sparse,spline-conv}的时候报错
  6. 扩散模型就是自动编码器!DeepMind研究学者提出新观点并论证
  7. Gartner:解开关于人工智能的六个迷思
  8. 一文看懂中国MEMS传感器产业链
  9. 深度学习巨头Yoshua Bengio清华演讲: 深度学习通往人类水平人工智能的挑战
  10. 华为公布车联网进展:年内将覆盖10万网联车