C ++ Implementation of Tree B
# Include
# Include
# Include
Using namespace std; class BTree {static const int M = 2; struct BTNode {int keyNum; int key [2 * M-1]; // keyword array struct BTNode * child [2 * M]; // child node array bool isLeaf;}; BTNode * root; // during insertion, ensure that the pNode node keyword is less than 2 * M-1 void InsertNonFull (BTNode * pNode, int key); // when the child node has 2 m-1 keywords, split this node void SplitChild (BTNode * parent, int I, BTNode * child); // combine the nodes of the two M-1 elements void merge (BTNode * parent, BTNode * pNode1, BTNode * pNode2, int in Dex); // find the largest keyword smaller than the first keyword of the pNode node, that is, the front node int predecessor (BTNode * pNode ); // locate the successor node int successor (BTNode * pNode); // pNode1 requests a node key [index] to the parent, and the parent requests a node to pNode0, pNode1 keyword count is M-1void ExchangeLeftNode (BTNode * parent, BTNode * pNode0, BTNode * pNode1, int index); void ExchangeRightNode (BTNode * parent, BTNode * pNode1, BTNode * pNode2, int index); // Delete, the number of node keywords is not less than Mvoid RemoveNonLess (BTNode * pNode, int key); void D IskWrite (BTNode * pNode); void DiskRead (BTNode * pNode); BTNode * Search (BTNode * pNode, int key, int & index); public: BTree ();~ BTree (); BTNode * search (int key, int & index); void insert (int key); void remove (int key); // print by level. Void PrintRow () ;}; BTree: BTree () {root = new BTNode (); root-> isLeaf = true; root-> keyNum = 0; diskWrite (root);} BTree ::~ BTree () {struct BTNode * pNode; queue
Q; q. push (root); while (! Q. empty () {pNode = q. front (); q. pop (); if (pNode-> isLeaf) continue; for (int I = 0; I <= pNode-> keyNum; I ++) q. push (pNode-> child [I]); delete pNode ;}} void BTree: DiskWrite (BTNode * pNode) {} void BTree: DiskRead (BTNode * pNode) {} BTree: BTNode * BTree: Search (BTNode * pNode, int key, int & index) {int I = 0; while (I
KeyNum & key> pNode-> key [I]) // locate the first subscript I ++ that is greater than or equal to the key; if (I <pNode-> keyNum & key = pNode-> key [I]) {// if a keyword is found, return index = I; return pNode ;} if (pNode-> isLeaf) // The leaf node has been found, and return NULL does not exist; else {DiskRead (pNode-> child [I]); return Search (pNode-> child [I], key, index); // recursive Search} void BTree :: insertNonFull (BTNode * pNode, int key) {int I = pNode-> keyNum-1; if (pNode-> isLeaf) {// if it is a leaf node, insert while directly (I> = 0 & key <PNode-> key [I]) {pNode-> key [I + 1] = pNode-> key [I]; I --;} pNode-> key [I + 1] = key; pNode-> keyNum ++; DiskWrite (pNode );} else {while (I >= 0 & key <pNode-> key [I]) I --; // locate the first subscript I ++ that is less than or equal to the key; diskRead (pNode-> child [I]); if (pNode-> child [I]-> keyNum = 2 * M-1) {// determine whether the child node has 2 * M-1 keywords, You need to split SplitChild (pNode, I, pNode-> child [I]); if (key> pNode-> key [I]) // if the key is greater than the element on the parent node, I ++;} InsertNonFull (pNode-> child [I], key); // saved Less than 2 * M-1 keywords} void BTree: SplitChild (BTNode * parent, int I, BTNode * child) {int j; struct BTNode * pNode = new BTNode (); pNode-> isLeaf = child-> isLeaf; pNode-> keyNum = M-1; for (j = 0; j <M-1; j ++) // assign the last M-1 keyword of the child node to the new node pNode-> key [j] = child-> key [j + M]; if (! Child-> isLeaf) {// if child is not a leaf node, assign the next M child nodes to the new node. For (j = 0; j <M; j ++) pNode-> child [j] = child-> child [j + M];} child-> keyNum = M-1; for (j = parent-> keyNum; j> I; j --) parent-> child [j + 1] = parent-> child [j]; // move the node pointer after the parent node parent subscript I of the child node to a backward position, parent-> child [j + 1] = pNode; // treat the newly generated node as a child of parent for (j = parent-> keyNum-1; j> = I; j --) // move all the keywords after I to a position following parent-> key [j + 1] = parent-> key [j]; parent-> key [j + 1] = child-> key [M-1]; // refers Fixed location parent-> keyNum ++; DiskWrite (parent); DiskWrite (pNode); DiskWrite (child);} void BTree: merge (BTNode * parent, BTNode * pNode1, BTNode * pNode2, int index) {pNode1-> key [M-1] = parent-> key [index]; for (int I = 0; I <M-1; I ++) // move the pNode2 keyword to pNode1 pNode1-> key [I + M] = pNode2-> key [I]; pNode1-> keyNum = 2 * M-1; if (! PNode1-> isLeaf) {// if it is not a leaf, move the child pointer of pNode2 to pNode1 for (int I = 0; I <M; I ++) pNode1-> child [I + M] = pNode2-> child [I];} for (int I = index; I <parent-> keyNum; I ++) {// move the keywords after the parent node index and the Child Pointer Forward a parent-> key [I] = parent-> key [I + 1]; parent-> child [I + 1] = parent-> child [I + 2];} parent-> keyNum --; delete pNode2;} int BTree :: predecessor (BTNode * pNode) {while (! PNode-> isLeaf) pNode = pNode-> child [pNode-> keyNum]; return pNode-> key [pNode-> keyNum-1];} int BTree :: successor (BTNode * pNode) {while (! PNode-> isLeaf) pNode = pNode-> child [0]; return pNode-> key [0];} void BTree: ExchangeLeftNode (BTNode * parent, BTNode * pNode0, BTNode * pNode1, int index) {for (int I = pNode1-> keyNum; I> 0; I --) pNode1-> key [I] = pNode1-> key [I-1]; // move all the keywords of the pNode1 node one pNode1-> key [0] = parent-> key [index]; // The 0th keywords are from the parent node pNode1-> keyNum ++; parent-> key [index] = pNode0-> key [pNode0-> keyNum-1]; // The keyword at the index of the parent node comes from the maximum keyword of pNode0 if (! PNode0-> isLeaf) {// if it is not a leaf node, for (int I = pNode1-> keyNum; I> 0; I --) // move the pointer of the child in pNode1 to one position, and assign the last child pointer of pNode0 to its first pNode1-> child [I] = pNode1-> child [I-1]; pNode1-> child [0] = pNode0-> child [pNode0-> keyNum];} pNode0-> keyNum --;} void BTree: ExchangeRightNode (BTNode * parent, BTNode * pNode1, BTNode * pNode2, int index) {pNode1-> key [pNode1-> keyNum] = parent-> key [index]; pNode1-> keyNum ++; parent-> key [index] = pNo De2-> key [0]; for (int I = 0; I <pNode2-> keyNum-1; I ++) pNode2-> key [I] = pNode2-> key [I + 1]; if (! PNode2-> isLeaf) {pNode1-> child [pNode1-> keyNum] = pNode2-> child [0]; for (int I = 0; I <pNode2-> keyNum; I ++) pNode2-> child [I] = pNode2-> child [I + 1];} pNode2-> keyNum --;} void BTree: RemoveNonLess (BTNode * pNode, int key) {if (pNode-> isLeaf) {// to the leaf node, directly Delete int I = 0; while (I
KeyNum & key> pNode-> key [I]) I ++; if (I <pNode-> keyNum & key = pNode-> key [I]) {while (I <pNode-> keyNum-1) {pNode-> key [I] = pNode-> key [I + 1]; I ++ ;} pNode-> keyNum --;} else {cout <"not found! "<Endl ;}} else {int I = 0; while (I <pNode-> keyNum & key> pNode-> key [I]) // find the first key keyword I ++; if (I <pNode-> keyNum & key = pNode-> key [I]) {// find the keyword struct BTNode * pNode1 = pNode-> child [I] in the node; struct BTNode * pNode2 = pNode-> child [I + 1]; if (pNode1-> keyNum> = M) {// if the number of children nodes on the left of the keyword is greater than or equal to Mint target = predecessor (pNode1 ); // move the forward node to pNode, pNode-> key [I] = target; RemoveNonLess (pNode1, target ); // recursively Delete target} else if (pNode2-> keyNum> = M) {// right side, similarly, int target = successor (pNode2 ); pNode-> key [I] = target; RemoveNonLess (pNode2, target);} else {merge (pNode, pNode1, pNode2, I); // all smaller than M, merge RemoveNonLess (pNode1, key) ;}} else {// in this node, struct BTNode * pNode1 = pNode-> child [I]; struct BTNode * pNode0 = NULL; struct BTNode * pNode2 = NULL; if (I> 0) pNode0 = pNode-> child [I-1]; // left node if (I <pNode-> keyNum) pNode2 = pNode-> child [I + 1]; // right node if (pNode1-> keyNum = M-1) {// if the number of child node keywords to be deleted is M-1if (I> 0 & pNode0-> keyNum> = M) {// If the left neighbor node has at least M keywords, borrow An ExchangeLeftNode (pNode, pNode0, pNode1, I-1);} else if (I <pNode-> keyNum & pNode2-> keyNum> = M) {// Similarly, ExchangeRightNode (pNode, pNode1, pNode2, I);} else if (I> 0) {// both adjacent nodes have only M-1 keywords, merge (pNode, pNode0, pNode1, I-1); pNode1 = pNode0;} else {merge (pNode, pNode1, pNode2, I);} RemoveNonLess (pNode1, key) ;}else {RemoveNonLess (pNode1, key) ;}}} BTree: BTNode * BTree: search (int key, int & index) {return Search (root, key, index);} void BTree: insert (int key) {struct BTNode * r = root; if (root-> keyNum = 2 * M-1) {// root node special processing, if the number of root node keywords is 2 * M-1, struct BTNode * pNode = new BTNode (); // create a new node as the new root node, use the current root node as root = pNode; // The child node pNode of The New root Node-> isLeaf = false; pNode-> keyNum = 0; pNode-> child [0] = r; SplitChild (pNode, 0, r); // The child node r has 2 * M-1 keyword InsertNonFull (pNode, key );} elseInsertNonFull (r, key);} void BTree: remove (int key) {if (root-> keyNum = 1) {// if the root node has only two children, struct BTNode * pNode1 = root-> child [0]; struct BTNode * pNode2 = root-> child [1]; if (pNode1-> keyNum = M-1 & pNode2-> keyNum = M-1) {// and both have only M-1 keywords, merge (root, pNode1, pNode2, 0); delete root; root = pNode1;} else {RemoveNonLess (root, key) ;}} else {RemoveNonLess (root, key) ;}} void BTree:: PrintRow () {struct BTNode * pNode; queue
Q; q. push (root); while (! Q. empty () {pNode = q. front (); q. pop (); cout <"["; for (int I = 0; I <pNode-> keyNum; I ++) cout <pNode-> key [I] <""; cout <"]" <endl; if (pNode-> isLeaf) continue; for (int I = 0; I <= pNode-> keyNum; I ++) q. push (pNode-> child [I]) ;}} int main (void) {BTree tree; tree. insert ('C'); tree. insert ('n'); tree. insert ('G'); tree. insert ('A'); tree. insert ('H'); tree. insert ('E'); tree. insert ('k'); tree. insert ('q'); tree. insert ('M'); tree. insert ('F'); tree. insert ('W'); tree. insert ('l'); tree. insert ('T'); tree. insert ('Z'); tree. insert ('D'); tree. insert ('P'); tree. insert ('R'); tree. insert ('x'); tree. insert ('y'); tree. insert ('s '); tree. remove ('n'); tree. remove ('B'); tree. printRow ();}