Question:
Because the leaf node does not need a pointer to its child, you can use a (larger) tvalue different from the internal node for disk pages of the same size. Describes how to modify the creation and insertion of Tree BProgramTo handle this deformation.
Thoughts:
Set the degree of a B tree to T, then a node contains up to 2 * T-1 keywords and 2 * t pointer, the size of the occupied is S = (2 * T-1) * sizeof (key) + (2 * t) * sizeof (child), the space for storing the child pointer is used to store the key without changing the s value, A maximum of S = s/sizeof (key) KEYWORDS can be stored, obtain S = (2 * T-1) + 8 * t/sizeof (key ), therefore, the leaf node degree t2 = T + 4 * t/sizeof (key ).
Modification method:
The split node of the leaf node is also the leaf node. The way to generate the internal node is obtained by a keyword rising after a node is split, even if the degree T2 of the leaf node is much larger than the Degree t of the internal node, you don't have to worry about splitting a leaf node into several internal nodes. In any case, a node will only be split into two nodes. Most programs do not need to change. The difference is that (1) the split conditions of leaf nodes and internal nodes are different (2) the number of key words to be copied between the split leaf node and internal node is different
The creation operation does not seem to need to be modified.
The insert operation must be modified in three places.
(1) p270, B-TREE-INSERT (T, k), L2, changed
Int t2 = T + 4 * t/sizeof (INT); If (R-> leaf = 1 & R-> N = 2 * t2-1) | (R-> leaf = 0 & R-> N = 2 * T-1 ))
(2) p270, B-TREE-INSERT-NOTFULL (x, k), l13, changed
Int I = x-> N, T2 = T + 4 * t/sizeof (INT ); if (X-> child [I]-> leaf = 1 & X-> child [I]-> N = 2 * t2-1) | (X-> child [I]-> leaf = 0 & X-> child [I]-> N = 2 * t-1 ))
(3) p269, B-TREE-SPLIT-CHILD (X, I, Y)
Before L1Code
If (Y-> leaf = 1) T2 = T + T * 4/sizeof (INT); else t2 = T;
After that, all t values are changed to T2.
Code:
# Include <iostream> using namespace STD; # define n 10int t = 2; // B-Tree node Structure struct node {int N; // Number of keywords currently stored in node x int key [N]; // n keywords, stored in non-descending order bool leaf; // true: false if X is a leaf: inner node * child [n + 1]; // pointer pointing to n + 1 child }; // B tree structure struct B _tree {// point to the root node * root;}; // disk read/write operation void disk_read (node * X) {} void disk_write (node * X) {} // construct an empty tree with Tree nodes void B _tree_create (B _tree * t) {// generate a root node * x = new node; // At the beginning, the root node is the leaf node X-> leaf = true; // At the beginning, there is no keyword X-> n = 0 in the root node; disk_write (X ); t-> root = x;} // split, split y into two nodes, and select a keyword to insert it to position I in X void B _tree_split_child (node * X, int I, node * Y) {Int J, T2; If (Y-> leaf = 1) T2 = T + T * 4/sizeof (INT ); else t2 = T; // generate a new node znode * z = new node; // split y into Y and Z, therefore, the leaf attribute of Z is the same as that of Y. Z-> leaf = Y-> leaf; // y has 2 T-1 keywords before split, and The T-1 before split belongs to y, the rear T-1 belongs to Z, and the middle t belongs to xz-> N = t2-1; y-> N = t2-1; // The following T-1 keywords are copied to zfor (j = 1; j <t2; j ++) z-> key [J] = Y-> key [J + T2]; // if there is a child, the child also needs to copy it. Originally there were 2 t child trees, the first t belongs to Y, and the last t belongs to zif (Y-> leaf = false) {for (j = 1; j <= t2; j ++) z-> child [J] = Y-> child [J + T2];} // use Z as the I + 1 child of X (Y is already the I child of X) for (j = x-> N + 1; j> I; J --) x-> child [J + 1] = x-> child [J]; X-> child [I + 1] = z; // Insert the T keyword in Y to the I position of X for (j = x-> N; j> = I; j --) x-> key [J + 1] = x-> key [J]; X-> key [I] = Y-> key [T2]; // X keyword + 1x-> N ++; disk_write (y); disk_write (z); disk_write (x );} // Insert the keyword K into a node X that is not full void B _tree_insert_nonfull (node * X, int K) {int I = x-> N, t2 = T + 4 * t/sizeof (INT); // If X is a leaf node if (X-> leaf) {// locate the inserted position while (I> = 1 & K <X-> key [I]) {X-> key [I + 1] = x-> key [I]; I --;} // Insert the keyword Kx-> key [I + 1] = K; x-> N ++; disk_write (x );} // if it is not the leaf node else {// find the inserted position while (I> = 1 & K <X-> key [I]) I --; I ++; // read its child and insert the keyword to its child. In two cases, disk_read (X-> child [I]); // if the child is full (X-> child [I]-> leaf = 1 & X-> child [I]-> N = 2 * t2-1) | (X-> child [I]-> leaf = 0 & X-> child [I]-> N = 2 * t-1 )) {// perform the split operation on the Child. After the split, the child will not become less than B _tree_split_child (X, I, X-> child [I]); if (k> X-> key [I]) I ++;} // if the child is not satisfied, insert B _tree_insert_nonfull (X-> child [I] directly to the child. k) ;}}// Insert the keyword kvoid B _tree_insert (B _tree * t, int K) to t {node * r = T-> root; int t2 = T + 4 * t/sizeof (INT ); // if the root node is full if (R-> leaf = 1 & R-> N = 2 * t2-1) | (R-> leaf = 0 & R-> N = 2 * T-1) {// apply for a new node * s = new node; // use the node as the root node T-> root = s; s-> leaf = false; s-> n = 0; s-> child [1] = R; // split the original root node into two nodes as The 0th and 1st children of S, respectively, B _tree_split_child (s, 1, R). // Insert the key word K into the root node, at this time, the root node must be less than B _tree_insert_nonfull (S, k);} // if the root node is less than else // Insert the keyword directly to the root node B _tree_insert_nonfull (R, k );} int main () {// generate a B-tree B _tree * t = new B _tree; B _tree_create (t); // Insert the keyword int I in sequence; for (I = 1; I <= 100; I ++) {B _tree_insert (t, I);} return 0 ;}