B树(平衡多路查找树)
来源:互联网 发布:mac无损播放器 编辑:程序博客网 时间:2024/06/06 06:33
1. B树是一种平衡的多路查找树,其中每一个节点的孩子数可以多于2个,且每一个节点可以存储多个元素。
2. 节点最大的孩子数目称为B树的阶。
一个M阶的B树具有以下属性:
. 如果根节点不是叶子节点,则至少有2棵子树。
. 每一个非根非叶子节点有M/2到M个孩子节点。
. 每一个非根节点有M/2-1到M-1个关键字,并且以升序排列。
. 所有的叶子节点都在同一层。
. 在一个节点中,指针Ai所指向子树中所有的节点的关键字均小于Ki,指针A(i+1)所指向子树中所有的节点的关键字均大于Ki。(i=0,1,2,3,......)
PS:M/2是向上取整
插入:
1. 当树为空树,直接插入。
2. 如果插入后的叶子节点的关键字的个数小于M-1,直接插入。
3. 如果插入后的叶子节点的关键字的个数为M,需分裂。
怎样分裂:
新创建一个节点,把节点从中间到后面的关键字和指针拷贝到新节点中,把中间的关键字插入到父节点中,把新创建的节点连接到父节点上,如果父节点的关键字的个数为M,则继续调整,否则停止。
如图:
当插入6后的图为:
结果叶子节点的关键字的个数等于M=3,根据B树的性质可知关键字的个数最大为M-1,则需要分裂,分裂后的图为:
代码:
#pragma oncetemplate<class K,int M>struct BTreeNode{ K _keys[M]; BTreeNode<K,M>* _subs[M+1];BTreeNode<K,M>* _parent;size_t _size; //记录关键字的个数 BTreeNode():_size(0),_parent(NULL) {for(size_t i=0;i<M;++i){_keys[i]=K();_subs[i]=NULL;}_subs[M]=NULL;}};template<class K,int M>class BTree{typedef BTreeNode<K,M> Node;public:BTree():_root(new Node){}bool Insert(const K& key){if(_root->_size ==0){_root->_keys [0]=key;_root->_size =1;return true;}//不是空树,找key是否存在pair<Node*,int> ret=Find(key);if(ret.second !=-1) //找到{return false;}//没找到,需插入Node* cur=ret.first;K newkey=key;Node* sub=NULL;while(1){//1.往cur中插入key//2.如果cur没满,停止,cur满了,继续调整 InsertKey(cur,newkey,sub);if(cur->_size <M)return true;//满了,分裂int mid=cur->_size /2;Node* tmp=new Node;size_t j=0;//新建一个节点,把右半边的key放到新建节点中for(size_t i=mid+1;i<cur->_size ;++i){tmp->_keys [j++]=cur->_keys [i];tmp->_size ++;cur->_keys [i]=K();}j=0;//新建一个节点,把右半边的孩子节点放到新建节点中for(size_t i=mid+1;i<cur->_size +1;++i){tmp->_subs [j]=cur->_subs [i];if(tmp->_subs [j])tmp->_subs [j]->_parent=tmp;++j;cur->_subs [i]=NULL;}//分裂的节点为根节点if(cur->_parent ==NULL){_root=new Node;_root->_keys [0]=cur->_keys [mid];cur->_keys [mid]=K();_root->_size =1;_root->_subs [0]=cur;_root->_subs [1]=tmp;cur->_parent =_root;tmp->_parent =_root;cur->_size -=(tmp->_size +1);return true;}else{newkey=cur->_keys [mid];cur->_keys [mid]=K();sub=tmp;cur->_size =mid;cur=cur->_parent ;}}}void InsertKey(Node* cur,const K& key,Node* sub){int i=cur->_size -1;while(i>=0){if(cur->_keys [i]<key)break;else {cur->_keys [i+1]=cur->_keys [i];cur->_subs [i+2]=cur->_subs [i+1];}--i;}cur->_keys [i+1]=key;cur->_subs [i+2]=sub;if(sub!=NULL)sub->_parent =cur; cur->_size ++;}//找到返回TRUE,没找到返回他的父亲节点pair<Node*,int> Find(const K& key){Node* cur=_root;Node* parent=cur;while(cur){size_t i=0;while(i<cur->_size ){if(cur->_keys[i]<key)++i;else if(cur->_keys [i]>key) //访问孩子节点{break;}else //找到keyreturn pair<Node*,int> (cur,i); //调用了匿名对象构造函数 } parent=cur;cur=cur->_subs [i];} //cur为空return pair<Node*,int> (parent,-1);}void InOrder(){_InOrder(_root);}protected:void _InOrder(Node* root){if(root==NULL)return;int i=0;for(i=0;i<root->_size;++i){_InOrder(root->_subs [i]);cout<<root->_keys [i]<<" ";}_InOrder(root->_subs [i]); //遍历最右边的孩子}private:Node* _root;};void TestBTree(){BTree<int,3> b;int arr[]={53,75,139,49,36,101};for(size_t i=0;i<sizeof(arr)/sizeof(arr[0]);++i){b.Insert (arr[i]);}b.InOrder ();}
1 0
- B树 平衡多路查找树
- B树(平衡多路查找树)
- B树(平衡多路查找树)B-tree树
- 动态查找---->B树(broad-tree 平衡多路查找树)
- 数据结构(9)平衡查找树之B树
- 平衡查找树之B树
- 平衡查找树之B树
- 平衡查找树之B树
- 平衡查找树之B树
- 平衡查找树之B树
- 四、平衡查找树之B树
- 平衡查找树之B树
- 二叉查找树(BST),平衡二叉查找树(AVL),红黑树(RBT),B~/B+树(B-tree)的比较
- 二叉查找树(BST),平衡二叉查找树(AVL),红黑树(RBT),B~/B+树(B-tree)的比较
- 二叉查找树(BST),平衡二叉查找树(AVL),红黑树(RBT),B~/B+树(B-tree)的比较
- 二叉查找树(BST),平衡二叉查找树(AVL),红黑树(RBT),B~/B+树(B-tree)的比较
- 二叉查找树(BST),平衡二叉查找树(AVL),红黑树(RBT),B~/B+树(B-tree)的比较
- 二叉查找树(BST),平衡二叉查找树(AVL),红黑树(RBT),B~/B+树(B-tree)的比较
- 在windows10下搭建Storm并运行WordCount详解(单机版)!
- 自定义控件
- python中MySQLdb的execute和executemany的使用
- Kafka的使用背景
- 软件工程各文档间的联系
- B树(平衡多路查找树)
- Mysql修改登录密码
- js中的onload
- oracle通过dblink连接mysql配置详解(全Windows下)
- Linux 安装
- mysql:安装
- opengl 光照
- 传输层流协议:RTP/RTCP、SCTP、DCCP、RTSP
- 【SSH网上商城项目实战16】Hibernate的二级缓存处理首页的热门显示