一、B树引入

二叉搜索树、平衡二叉树、红黑树都是动态查找树,典型的二叉搜索树结构,查找的时间复杂度和树的高度相关O(log2N)。

1)数据杂乱无章-------线性查找--O(n)

2)数据有序-------二分查找 ---O(log 2 n)  最差退化成单支树-----线性结构

3)二叉搜索树、AVL树、红黑树 --------O(log2 n)

数据一般保存在磁盘上,若数据量过大不能全部加载到内存,为了访问所有数据,使用如下搜索树结构保存数据:树的结点中保存权值和磁盘的地址

那如何加速对数据的访问速度呢?

提高I/O的时间

降低树的高度--平衡多叉树

二、B树定义

1970年,R.Bayer和E.mccreight提出了一种适合外查找的树,它是一种平衡的多叉树,称为B树。
(有些地方写的是B-树,注意不要误读成"B减树")
一棵M阶(M>2)的B树,是一棵平衡的M路平衡搜索树,可以是空树或者满足一下性质:
1. 根节点至少有两个孩子
2. 每个非根节点至少有M/2(上取整)个孩子,至多有M个孩子
3. 每个非根节点至少有M/2-1(上取整)个关键字,至多有M-1个关键字,并且以升序排列

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

一次插入的过程:53, 75, 139, 49, 145, 36, 101

#pragma once
#include <iostream>
#include <stdlib.h>using namespace std;template<class K, int M>
struct BTreeNode
{typedef BTreeNode<K, M> Node;K _keys[M];//多给一个位置是为了先插入方便分裂Node* _sub[M+1];Node* _parent;size_t _size;//记录关键字的个数BTreeNode():_parent(NULL),_size(0){for(size_t i = 0; i < M; i++){_keys[i] = K();_sub[i] = 0;}_sub[M] = 0;}
};template<class K, int M>
class BTree
{typedef BTreeNode<K, M> Node;
public:BTree():_pRoot(NULL){}void Inorder(){_Inorder(_pRoot);}~BTree(){_Destroy(_pRoot);}bool Insert(const K& key){if(NULL == _pRoot){_pRoot = new Node();_pRoot->_keys[0] = key;_pRoot->_size++;return true;}pair<Node*, size_t> temp = _Find(key);if(temp.second != -1){return false;}Node* cur = temp.first;Node* sub = NULL;K newKey = key;while(1){_InsertKey(cur, newKey, sub);if(cur->_size < M){return true;}while(cur->_size >= M){size_t mid = cur->_size / 2;Node* NewNode = new Node;for(size_t i = mid+1; i < cur->_size; i++){int j = 0; //新节点的下标NewNode->_keys[j] = cur->_keys[i];NewNode->_size++;cur->_keys[i] = K();//复制之后,对应的原位置key置为初始值。j++;}int j = 0;for(size_t i = mid+1; i < cur->_size+1; i++){NewNode->_sub[j] = cur->_sub[i];if(NewNode->_sub[j])NewNode->_sub[j]->_parent = NewNode;j++;cur->_sub[i] = NULL;}if(cur == _pRoot){Node* temp = new Node();temp->_keys[0] = cur->_keys[mid];cur->_keys[mid] = K();cur->_size = mid;temp->_size++;temp->_sub[0] = cur;cur->_parent = temp;temp->_sub[1] = NewNode;NewNode->_parent = temp;_pRoot = temp;return true;}newKey = cur->_keys[mid];cur->_keys[mid] = K();cur->_size = mid;sub = NewNode;}cur = cur->_parent;}}protected:pair<Node*, size_t> _Find(const K& key){Node* cur = _pRoot;Node* parent = NULL;while(cur){size_t i = 0;while(i < cur->_size){if(cur->_keys[i] < key)i++;else if(cur->_keys[i] > key)break;elsereturn pair<Node*, size_t>(cur, i);}parent = cur;cur = cur->_sub[i];}return pair<Node*, size_t>(parent, -1);}void _InsertKey(Node* cur,const K& Key,Node* sub){int i = cur->_size-1;while(i >= 0){if(cur->_keys[i] > Key){//移动关键字位置cur->_keys[i+1] = cur->_keys[i];//移动子树的位置cur->_sub[i+2] = cur->_sub[i+1];i--;}elsebreak;}cur->_keys[i+1] = Key;cur->_sub[i+2] = sub;if(sub)sub->_parent = cur;cur->_size++;}void _Inorder(Node* _pRoot){if(NULL == _pRoot)return;size_t i = 0;for(; i < _pRoot->_size; i++){_Inorder(_pRoot->_sub[i]);cout<<_pRoot->_keys[i]<<" ";}_Inorder(_pRoot->_sub[i]);}void _Destroy(Node* _pRoot){if(NULL == _pRoot)return;size_t i = 0;for(; i < _pRoot->_size; i++){_Destroy(_pRoot->_sub[i]);delete _pRoot->_sub[i];}_Destroy(_pRoot->_sub[i]);delete _pRoot->_sub[i];}private:Node* _pRoot;
};void test()
{BTree<int, 3> bt;int array[] = {53, 75, 139, 49, 145, 36, 101};for(int i = 0; i < sizeof(array)/sizeof(array[0]); i++){bt.Insert(array[i]);}bt.Inorder();
}

数据结构:神奇的B树实现解析(有图有代码有真相!!!)相关推荐

  1. Java数据结构之链表、树、堆、图手写双向非循环链表

    数据结构.手写双向非循环链表 文章目录 数据结构.手写双向非循环链表 链表 1.链表的分类 2.链表的特点 二.手写双向非循环链表 2.1方法总结 2.2 环境搭建 2.3 add 添加结点 2.3. ...

  2. Linux:多进程、多线程服务器的实现解析(有图有代码有真相!!!)

    一.问题引入 阻塞型的网络编程接口 几乎所有的程序员第一次接触到的网络编程都是从 listen().send().recv()等接口开始的.使用这些接口可以很方便的构建服务器 /客户机的模型. 我们假 ...

  3. 数据结构---判断一棵树是否是二叉搜索树

    数据结构-判断一棵树是否是二叉搜索树 代码: #pragma once #define N 100 #define elemType BTree* #include<stdlib.h> t ...

  4. 数据结构和算法——kd树

    一.K-近邻算法 K-近邻算法是一种典型的无参监督学习算法,对于一个监督学习任务来说,其 m m个训练样本为: {(X(1),y(1)),(X(2),y(2)),⋯,(X(m),y(m))} \lef ...

  5. 常见数据结构和算法实现(排序/查找/数组/链表/栈/队列/树/递归/海量数据处理/图/位图/Java版数据结构)

    常见数据结构和算法实现(排序/查找/数组/链表/栈/队列/树/递归/海量数据处理/图/位图/Java版数据结构) 数据结构和算法作为程序员的基本功,一定得稳扎稳打的学习,我们常见的框架底层就是各类数据 ...

  6. PTA 树的同构 思路分析及代码解析

    PTA 树的同构 思路分析及代码解析 v1.0 一.前导 1. 需要掌握的知识 2. 题目信息 二.解题思路分析 1. 题意理解 2. 思路分析(重点) 三.具体实现 1. 弯路和bug 2. 代码框 ...

  7. 数据结构系列之B树、B+树、B*树

    第一节.B树.B+树.B*树 1.前言: 动态查找树主要有:二叉查找树(Binary Search Tree),平衡二叉查找树(Balanced Binary Search Tree),红黑树(Red ...

  8. 数据结构与算法——AVL树类的C++实现

    关于AVL树的简单介绍能够參考: 数据结构与算法--AVL树简单介绍 关于二叉搜索树(也称为二叉查找树)能够參考:数据结构与算法--二叉查找树类的C++实现 AVL-tree是一个"加上了额 ...

  9. 数据结构:关于AVL树的平衡旋转详解

    前言 本文是基于你已经有一定的二叉排序树知识.如果你还是小白,可以参考我之前的博客:<数据结构:二叉搜索树(BST)的基本操作>.所以,在本文中不会再出现关于BST树的基本知识. 版权说明 ...

最新文章

  1. wxWidgets刚開始学习的人导引(3)——wxWidgets应用程序初体验
  2. dedecms 会员网站UID注册名转MID
  3. 通过IDE生成和手动call调用webservice
  4. WPF中退出时显示是否保存数据提示
  5. 雷军喊你报考武汉大学
  6. 从新手到高手 c++全方位学习_股票新手怎样快速入门?关于散户学习炒股的几点建议...
  7. Python 图形 GUI 库 pyqtgraph
  8. t-sql还原数据库_如何更新T-SQL工具箱数据库
  9. 1、Android-活动(下)
  10. 基于SSM的电影购票系统
  11. 自动驾驶 2-5 自动驾驶汽车的未来 The Future of Autonomous Vehicles
  12. 计算机网络安全 单词
  13. java 项目启动后页面乱码_java生成的Html打开后展示乱码
  14. android 蓝牙转串口_android蓝牙串口通讯
  15. Lync Server 服务器版本升级
  16. Exp4 恶意代码分析 20154328 常城
  17. autoit3转换php,AutoIt3调用动态链接库DLL
  18. c语言编程对电脑配置的要求,请问学习电脑编程需要什么配置的笔记本电脑?价格多少?...
  19. UVA 213 - Message Decoding 简单题 lambda表达式 23333333
  20. c语言修仙亲吻片段,《C语言修仙》by一十四洲,摘抄

热门文章

  1. ISLR—第二章 Statistical Learning
  2. Zookeeper客户端Curator使用详解
  3. metric learning -- 马氏距离与欧氏距离
  4. Xcode 修改工程名以及注意事项
  5. (一)prometheus与grafana介绍与安装
  6. MySQL运维系列 之 如何监控大事务
  7. 欧盟通过最新《数据保护法》
  8. VMware Workstation 8下Ubuntu 13.04中安装VMware Tools出错
  9. 时隔一年俺又回来了..
  10. 设计模式常见面试真题详解