B+树练习

  1 #ifndef BTREE_H  
  2 #define BTREE_H  
  3   
  4 #include  
  5 #include  
  6 const int maxValue=10000;  
  7   
  8 /////////////////////////////////////////////////  
  9 //BTreeNodeB树的结点的定义  
 10 /////////////////////////////////////////////////  
 11 template  
 12 struct BTreeNode  
 13 {  
 14         int n;                      //结点中关键码的个数  
 15         BTreeNode* parent;       //当前结点的父结点的指针  
 16          
 17         T* key;                     //m+1个元素存放关键码,其中key[0]和key[m]没有用  
 18         BTreeNode**              //子树指针的结点数组(一共有m棵子树),m+1个元素  
 19                 subTree;                //最后一个元素subTree[m]在插入溢出的时候使用  
 20         int** recptr;               //每个索引项中指向数据区相应记录起始地址的指针数组  
 21     BTreeNode(int m)            //构造函数  
 22         {  
 23                 n=0;                    //关键码个数初始化为0  
 24                 parent=NULL;            //父结点指针初始化为空  
 25                 key=new T[m+1];         //开辟关键码数组的空间  
 26                 subTree=new             //开辟子树的指针数组的内存空间  
 27                         BTreeNode*[m+1]; //从p0,p1,p2,...p(m-1)共m棵子树  
 28                 for(int i=0;i<=m;i++)     
 29                         subTree中  
 30         {  
 31                 for(int i=1;i<=n;i++)   //寻找插入关键码的位置  
 32                 {  
 33                         if(x  
 34                 key中  
 35                         subTree[j+1]=subTree[j];  
 36                 subTree<<" ";  
 37         };  
 38 };  
 39 /////////////////////////////////BTree定义结束  
 40   
 41 /////////////////////////////////////////////////  
 42 //Triple结构 返回搜索结果用的三元组  
 43 /////////////////////////////////////////////////  
 44 template  
 45 struct Triple  
 46 {  
 47         BTreeNode* r;            //结点指针  
 48         int i;                      //关键码在当前结点中的序号  
 49         int tag;                    //tag=0:搜索成功,tag=1:搜索失败  
 50 };  
 51 ////////////////////////////////Triple结构结束  
 52   
 53 /////////////////////////////////////////////////  
 54 //BTree  B树的定义;  
 55 //m阶B树的根至少有两个子树,  
 56 //其他的结点至少应该有int(m/2)+1个子树  
 57 //所有的失败结点都在一个层次上  
 58 /////////////////////////////////////////////////  
 59 template  
 60 class BTree  
 61 {  
 62 private:  
 63         BTreeNode* root;         //树根结点指针  
 64         int m;                      //即B树的阶数  
 65 public:  
 66         BTree(int x)                //空构造函数,构造一棵空x路的搜索树  
 67         {root=NULL;m=x;};  
 68         BTree(int x,BTreeNode* r)  
 69         {root=r;m=x;};              //用指定的树根来初始化当前的m路搜索树  
 70         void Insert(                //在树指定父结点的情况下插入一个结点  
 71                 BTreeNode* pa,       //指定要出入的位置的父结点  
 72                 BTreeNode* subTree,  //要插入的结点的指针  
 73                 int i);                 //表示插入到pa的第i个子树的位置  
 74          
 75         Triple                   //搜索指定关键码x对应的结点  
 76                 Search(const T& x);  
 77         void RootFirst(             //递归:以先根的方式遍历当前的搜索树  
 78                 BTreeNode* subTree);        
 79         void RootFirst()            //调用上面的递归函数  
 80         {RootFirst(root);};  
 81         bool Insert(const T& x);    //B树的插入操作  
 82         void Display(  
 83                 BTreeNode* p,int i); //递归:以缩进的格式显示当前的B树  
 84         void Display()              //调用上面的递归函数  
 85         {cout<<"*****当前B树的缩进结构显示*****:"<  
 86         Display(root,1);};  
 87 };  
 88 //////////////////////////////////////B树声明结束  
 89   
 90 /////////////////////////////////////////////////  
 91 //RootFirst()公有成员函数  
 92 //以先根的方式递归遍历当前B树  
 93 /////////////////////////////////////////////////  
 94 template  
 95 void BTree::RootFirst(BTreeNode* st)  
 96 {  
 97         if(st!=NULL)  
 98         {  
 99             int n=st->n;  
100             cout<<"当前结点有"<  
101                     <<"个关键码:"<  
102             for(int k=1;k<=n;k++)       //输出当前结点的所有的关键码  
103                     cout<key[k]<<" ";  
104             cout<<  
105             for(int i=0;i<=n;i++)       //递归输出所有的子树  
106                 RootFirst(st->subTree==x)      //如果找到  
107                         {  
108                                 result.r=ptr;       //当前查找驻留的结点指针  
109                                 result.i=i;         //查找成功的关键码  
110                                 result.tag=1;       //是否查找成功  
111                                 return result;  
112                         };  
113                         if(ptr->key;      //从失配的关键码左边的子树继续查找  
114         };  
115         /*如果查找失败*/  
116         result.r=pre;  
117         result.i=i;                     //可以在i-1和i之间进行插入  
118         result.tag=0;                   //查找失败  
119   
120         return result;  
121 };  
122 /////////////////////////////////Search()函数结束  
123   
124 /////////////////////////////////////////////////  
125 //Insert()公有成员函数  B树的插入操作  
126 //把指定的关键码插入到B树中,使得仍然满足B树的要求  
127 //首先对B树进行搜索,如果关键码已经存在则插入失败,  
128 //否则执行插入,并按B树要求进行调整  
129 //一般来说,执行插入的肯定是在叶子结点上进行  
130 //但是如果查找成功的话,可能在非叶子结点上就结束了  
131 /////////////////////////////////////////////////  
132 template  
133 bool BTree::Insert(const T& x)  
134 {  
135         /*如果当前的B树是空的,就新建之*/  
136         if(root==NULL)                  //如果当前的B树是空的  
137         {  
138                 root=new BTreeNode(m);   //新建一个结点  
139                 root->Insert(x,NULL);            //把关键码插入到key[]数组第一个位置  
140                 return true;  
141         };  
142   
143     /*如果当前的B树不空,就搜索该树*/  
144         Triple Tp;                   //查找结果三元组  
145         Tp=Search(x);  
146         int IsIn=Tp.tag;  
147         if(IsIn==1)                     //关键码已经存在  
148         {  
149                 cout<<"关键码已存在!"<  
150                 return false;               //插入失败  
151         };  
152   
153         /*插入关键码直到结点关键码不溢出为止*/  
154         BTreeNode* ptr=Tp.r;         //查找失败而驻留的结点  
155         int loc=Tp.i-1;                 //在k[loc]后进行插入  
156         int pkey=x;  
157         BTreeNode* p=NULL;           //随关键一起要插入的右子树的根结点  
158     do  
159         {  
160                 ptr->Insert(pkey,p);        //把关键码和相关的新分裂的右结点插入当前结点  
161                 if(ptr->n>m-1)              //如果关键码溢出,则需要进行调整  
162                 {  
163                         /*以下处理结点的分裂*/  
164                         int k=ptr->key[m/2+1];  //提取出要上提的关键码  
165                         BTreeNode* right     //建立分裂后右边的结点  
166                                 =new BTreeNode(m);  
167                         right->n=ptr->n-m/2-1;  //右结点的关键码个数  
168                         for(int i=m/2+2;i<=ptr->n;i++)  
169                                 right->key //把右半边的关键码复制进入右结点  
170                                 =ptr->key       
171                                 =ptr->subTree=k;     //插入新关键码  
172                                 newp->subTree[0]    //新关键码左边的子树  
173                                         =ptr;  
174                                 newp->subTree[1]    //新关键码右边的子树  
175                                         =right;  
176                                 newp->n=1;          //新关键码个数为1  
177                                 ptr->parent=newp;   //设置父结点指针  
178                             right->parent=newp;  
179                                 root=newp;  
180                                 return true;        //插入成功并结束  
181                         }  
182                         else                    //如果有父结点存在  
183                                 ptr=ptr->parent;    //把上提的关键码继续插入父结点  
184                 }  
185                 else                        //不溢出则插入成功  
186                         return true;  
187         }while(ptr!=NULL);  
188   
189         return true;  
190 };  
191 /////////////////////////Insert()公有成员函数结束  
192   
193 /////////////////////////////////////////////////  
194 //Display()公有成员函数    
195 //递归:显示当前B树的缩进格式  
196 /////////////////////////////////////////////////  
197 template  
198 void BTree::Display(BTreeNode* p,int i)  
199 {  
200         if(p!=NULL)  
201         {  
202                 for(int j=0;j  
203                         cout<<" ";          //控制缩进的格数  
204                 cout<<"当前结点是:关键码个数"<n<<" "  
205                         <<"关键码的内容是";  
206                 for(int k=1;k<=p->n;k++)//显示当前结点所有关键码  
207                         cout<key[k]<<" ";  
208             cout<  
209                 for(k=0;k<=p->n;k++)    //递归显示子树,递归向后缩进  
210                         Display(p->subTree[k],i+5);  
211         };  
212 };  
213 ////////////////////////////////Display()函数结束  
214   
215 #endif  
216   
217 #include"BTree.h"  
218   
219 /////////////////////////////////////////////////  
220 //main()函数  测试B树的程序  
221 /////////////////////////////////////////////////  
222 int main()  
223 {  
224         BTree BT(3);  
225         BT.Insert(53);      //依此在B树中插入关键码  
226         BT.Insert(75);  
227         BT.Insert(139);  
228         BT.Insert(49);  
229         BT.Insert(145);  
230         BT.Insert(36);  
231         BT.Insert(101);  
232         BT.Insert(150);  
233         BT.Insert(170);  
234         BT.Insert(25);  
235         BT.Insert(13);       
236   
237         BT.Display();      //显示当前B树的内容  
238         return 0;  
239 };  

 

posted @ 2017-04-05 15:06  稻草人H  阅读(601)  评论(0编辑  收藏  举报