【数据结构】B树(B-Tree)

前端之家收集整理的这篇文章主要介绍了【数据结构】B树(B-Tree)前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
B树
1970年,R.Bayer和E.mccreight提出了一种适合外查找的树,它是一种平衡的多叉树,称为B树。(有些地方写的是B-树,注意不要误读
成"B减树")
一棵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: 是向上取整

B树是一种高度平衡树

这里以M=3为例进行解释

例如一个树中有数组int arr[]={3,4,10,15,16,20,30,35,36,40,45,46,50,76,77};那么它的结构如下图


B树的插入

例如插入20 30 10 ,画图分析如下



代码

  1. #pragma once
  2. #include <vector>
  3. #include <iostream>
  4. using namespace std;
  5. template<class K,int M>
  6. struct BTreeNode
  7. {
  8. K _keys[M];//关键字数组,多一个便于分解
  9. BTreeNode<K,M>* _subs[M+1];//连接子树的指针数组
  10. BTreeNode<K,M>* _parent;
  11. int size;//关键字个数
  12.  
  13. BTreeNode()
  14. :size(0),_parent(NULL)
  15. {
  16. size_t i=0;
  17. for (i=0;i<M;++i)
  18. {
  19. _keys[i]=K();
  20. _subs[i]=NULL;
  21. }
  22. _subs[M]=NULL;
  23. }
  24.  
  25. };
  26. template<class K,int M>
  27. class BTree
  28. {
  29. typedef BTreeNode<K,M> Node;
  30. public:
  31. BTree()
  32. :_root(NULL)
  33. {}
  34. pair<Node*,int> Find(const K& key)
  35. {
  36. Node* cur=_root;
  37. Node* parent=NULL;
  38. while(cur)
  39. {
  40. int i=0;
  41. while(i<cur->size)
  42. {
  43. if(cur->_keys[i]<key)
  44. {
  45. ++i;
  46. }
  47. else if (cur->_keys[i]>key)
  48. {
  49. break;
  50. }
  51. else//找到关键字
  52. {
  53. return pair<Node*,int>(cur,i);
  54. }
  55. }
  56. parent=cur;
  57. cur=cur->_subs[i];
  58. }
  59. return pair<Node*,int>(parent,-1);//没有找到关键字返回-1;
  60. }
  61. bool Insert(const K& key)
  62. {
  63. if(_root==NULL)//空树的插入
  64. {
  65. _root=new Node;
  66. _root->_keys[0]=key;
  67. _root->size=1;
  68. return true;
  69. }
  70. pair<Node*,int> ret=Find(key);
  71. if(ret.second!=-1)//如果没有找到则插入,找到则不插入
  72. return false;
  73.  
  74. Node* cur=ret.first;
  75. K newkey=key;
  76. Node* sub=NULL;
  77. while(1)
  78. {
  79. InsertKey(cur,newkey,sub);
  80. if(cur->size<M)//如果插入后没有满,则直接返回
  81. return true;
  82.  
  83. size_t mid=cur->size/2;//插入后导致M满了,进行分裂
  84. Node* tmp=new Node;
  85. int j=0;
  86. for(int i=mid+1;i<cur->size;++i)//拷贝key及孩子,连续分裂
  87. {
  88. tmp->_keys[j]=cur->_keys[i];
  89. if (cur->_subs[i])
  90. {
  91. tmp->_subs[j]=cur->_subs[i];
  92. tmp->_subs[j+1]=sub;
  93. cur->_subs[i]=NULL;
  94.  
  95. tmp->_subs[j]->_parent=tmp;
  96. tmp->_subs[j+1]->_parent=tmp;
  97. }
  98. tmp->size++;
  99. cur->_keys[i]=K();
  100. cur->size--;
  101. j++;
  102. }
  103.  
  104. if(cur->_parent==NULL)//分裂到根节点
  105. {
  106. _root=new Node;
  107. _root->_keys[0]=cur->_keys[mid];
  108. _root->_subs[0]=cur;
  109. _root->_subs[1]=tmp;
  110. _root->size++;
  111.  
  112. cur->_keys[mid]=K();
  113. cur->size--;
  114.  
  115. cur->_parent=_root;
  116. tmp->_parent=_root;
  117.  
  118. return true;
  119. }
  120. //没有分裂到根节点
  121. newkey=cur->_keys[mid];
  122. cur->_keys[mid]=K();
  123. cur->size--;
  124. sub=tmp;
  125. cur=cur->_parent;//上移
  126. }
  127.  
  128. return true;
  129. }
  130. void Inorder()
  131. {
  132. _Inorder(_root);
  133. cout<<endl;
  134. }
  135. protected:
  136. void InsertKey(Node* node,const K& key,Node* sub)
  137. {
  138. int i=node->size-1;
  139. while (i>=0)
  140. {
  141. if(node->_keys[i]>key)
  142. {
  143. node->_keys[i+1]=node->_keys[i];
  144. node->_subs[i+2]=node->_subs[i+1];
  145. --i;
  146. }
  147. else
  148. {
  149. break;
  150. }
  151. }
  152. node->_keys[i+1]= key;
  153. node->_subs[i+2]=sub;
  154. if(sub)
  155. sub->_parent=node;
  156. node->size++;
  157. }
  158. void _Inorder(Node* root)//打印完一个子树再递归下一步进行打印
  159. {
  160. if(root==NULL)
  161. return;
  162. _Inorder(root->_subs[0]);
  163. for (int i=0;i<root->size;i++)
  164. {
  165. // _Inorder(root->_subs[i]);
  166. cout<<root->_keys[i]<<" ";
  167. }
  168. for(int i=1;i<M;++i)
  169. {
  170. _Inorder(root->_subs[i]);
  171. }
  172. }
  173. private:
  174. Node* _root;
  175. };
  176. void testBTree()
  177. {
  178.  
  179. BTree<int,3> bt;
  180. int arr[]={53,75,139,49,145,36,101};
  181. for(int i=0;i<sizeof(arr)/sizeof(arr[0]);++i)
  182. {
  183. bt.Insert(arr[i]);
  184. }
  185. bt.Inorder();
  186. }
  187.  

  1. #include "BTree.h"
  2. #include <cstdlib>
  3. int main()
  4. {
  5. testBTree();
  6.  
  7. system("pause");
  8. return 0;
  9. }

中序遍历结果为

猜你在找的数据结构相关文章