public override void Split(TreeNode twoFourNode, int element) { TwoFourTreeNode p; twoFourNode = (TwoFourTreeNode) twoFourNode; if (twoFourNode.parent == null) { p = new TwoFourTreeNode(); } else { p = (TwoFourTreeNode) twoFourNode.parent; } TwoFourTreeNode n1 = new TwoFourTreeNode(); TwoFourTreeNode n2 = new TwoFourTreeNode(); int[] elements = { element, twoFourNode.elements[0], twoFourNode.elements[1], twoFourNode.elements[2] }; int middle; this.SortElements(elements, elements.Length); n1.elements[0] = elements[0]; n1.elements[1] = elements[1]; n2.elements[0] = elements[3]; middle = elements[2]; n1.parent = p; n2.parent = p; if (p.NumberOfElements() == 0) { p.children[0] = n1; p.children[1] = n2; this.root = p; } else if (p.NumberOfElements() == 1) { if (n2.elements[0] < p.elements[0]) { p.children[2] = p.children[1]; p.children[0] = n1; p.children[1] = n2; } else { p.children[1] = n1; p.children[2] = n2; } } else if (p.NumberOfElements() == 2) { if (n2.elements[0] < p.elements[0] && n2.elements[0] < p.elements[1]) { p.children[3] = p.children[2]; p.children[2] = p.children[1]; p.children[0] = n1; p.children[1] = n2; } else if (n1.elements[1] > p.elements[0] && n1.elements[1] > p.elements[1]) { p.children[2] = n1; p.children[3] = n2; } else { p.children[3] = p.children[2]; p.children[1] = n1; p.children[2] = n2; } } else if (p.NumberOfElements() == 3) { if (n2.elements[0] < p.elements[0]) { p.children[4] = p.children[3]; p.children[3] = p.children[2]; p.children[2] = p.children[1]; p.children[1] = n2; p.children[0] = n1; } else if (n1.elements[0] > p.elements[0] && n2.elements[0] < p.elements[1]) { p.children[4] = p.children[3]; p.children[3] = p.children[2]; p.children[2] = n2; p.children[1] = n1; } else if (n1.elements[0] > p.elements[1] && n2.elements[0] < p.elements[2]) { p.children[4] = p.children[3]; p.children[3] = n2; p.children[2] = n1; } else { p.children[3] = n1; p.children[4] = n2; } } //if it is not a leaf check if (twoFourNode.IsLeaf() == false) { twoFourNode.children[0].parent = n1; twoFourNode.children[1].parent = n1; twoFourNode.children[2].parent = n1; twoFourNode.children[3].parent = n2; twoFourNode.children[4].parent = n2; n1.children[0] = twoFourNode.children[0]; n1.children[1] = twoFourNode.children[1]; n1.children[2] = twoFourNode.children[2]; n2.children[0] = twoFourNode.children[3]; n2.children[1] = twoFourNode.children[4]; } if (p.NumberOfElements() == 3) { this.Split(p, middle); } else if (p.NumberOfElements() < this.limit) { p.elements[p.NumberOfElements()] = middle; this.SortElements(p.elements, p.NumberOfElements()); } }
void TakeElementFromThreeNextRightSibling(TwoFourTreeNode p, TwoFourTreeNode node) { node.elements[0] = p.elements[0]; p.elements[0] = p.children[1].elements[0]; p.children[1].elements[0] = p.elements[1]; p.elements[1] = p.children[2].elements[0]; p.children[2].elements[0] = p.elements[2]; p.elements[2] = p.children[3].elements[0]; if (p.children[3].NumberOfElements() == 2) { p.children[3].elements[0] = p.children[3].elements[1]; p.children[3].elements[1] = 0; } else if (p.children[3].NumberOfElements() == 3) { p.children[3].elements[0] = p.children[3].elements[1]; p.children[3].elements[1] = p.children[3].elements[2]; p.children[3].elements[2] = 0; } if (node.IsLeaf() == false) { node.children[1] = p.children[1].children[0]; p.children[1].children[0] = p.children[1].children[1]; p.children[1].children[1] = p.children[2].children[0]; p.children[2].children[0] = p.children[2].children[1]; p.children[2].children[1] = p.children[3].children[0]; if (p.children[3].NumberOfElements() == 1) { p.children[3].children[0] = p.children[3].children[1]; p.children[3].children[1] = p.children[3].children[2]; p.children[3].children[2] = null; } else if (p.children[3].NumberOfElements() == 2) { p.children[3].children[0] = p.children[3].children[1]; p.children[3].children[1] = p.children[3].children[2]; p.children[3].children[2] = p.children[3].children[3]; p.children[3].children[3] = null; } node.children[1].parent = node; p.children[1].children[1].parent = p.children[1]; p.children[2].children[1].parent = p.children[2]; } }
//completes the deletion when node n is empty by either, removing the root, redistributing values, or merging nodes. //Note : if n is internal, it has only one child public void Fix(TwoFourTreeNode node) { TwoFourTreeNode p; if (node.parent == null) //No parent means it is root node { if (node.children[0] == null) { return; } //remove root and set the children as a root this.root = node.children[0]; this.root.parent = null; } else { p = (TwoFourTreeNode)node.parent; //situation represents both the possibility of merge and the sibling with two elements //if it returns -1, means there is no siblings with two elements //if it is bigger than -1, means that index has the two elements int situation = this.HasChildWithTwoElement(p); //check for redistrubution is possible or not if (situation > -1) { //redistrubute this.Redistrubute(node, p, situation); } //redistrubuting not possible, thus merge //for merging we have 5 different situation; 2 for parent with one element, 3 for parent with two element else { this.Merge(node); } if (node.parent.NumberOfElements() == 0) { this.Fix(p); } } }
void Redistrubute(TwoFourTreeNode node, TwoFourTreeNode p, int situation) { //there is two different situation if the parent has two nodes if (p.NumberOfElements() == 1) { if (situation == 20 || situation == 30) { this.TakeElementFromNextLeftSibling(p, node, 0); } else { this.TakeElementFromNextRightSibling(p, node, 0); } } //there is six different situation if the parent has three nodes else if (p.NumberOfElements() == 2) { //Check for which children is empty if (p.children[0].NumberOfElements() == 0) { //situation can be 1 or 2 if (situation == 21 || situation == 31) { this.TakeElementFromNextRightSibling(p, node, 0); } else { this.TakeElementFromTwoNextRightSibling(p, node, 0); } } else if (p.children[1].NumberOfElements() == 0) { //situation can be 0 or 2 if (situation == 20 || situation == 30) { this.TakeElementFromNextLeftSibling(p, node, 0); } else { this.TakeElementFromNextRightSibling(p, node, 1); } } else if (p.children[2].NumberOfElements() == 0) { //situation can be 0 or 1 if (situation == 20 || situation == 30) { this.TakeElementFromTwoNextLeftSibling(p, node, 2); } else { this.TakeElementFromNextLeftSibling(p, node, 1); } } } else if (p.NumberOfElements() == 3) { //Check for which children is empty if (p.children[0].NumberOfElements() == 0) { //situation can be 1 2 or 3 switch (situation) { case 21: this.TakeElementFromNextRightSibling(p, node, 0); break; case 31: this.TakeElementFromNextRightSibling(p, node, 0); break; case 22: this.TakeElementFromTwoNextRightSibling(p, node, 0); break; case 32: this.TakeElementFromTwoNextRightSibling(p, node, 0); break; case 23: this.TakeElementFromThreeNextRightSibling(p, node); break; case 33: this.TakeElementFromThreeNextRightSibling(p, node); break; } } else if (p.children[1].NumberOfElements() == 0) { //situation can be 0 2 or 3 switch (situation) { case 20: this.TakeElementFromNextLeftSibling(p, node, 0); break; case 30: this.TakeElementFromNextLeftSibling(p, node, 0); break; case 22: this.TakeElementFromNextRightSibling(p, node, 1); break; case 32: this.TakeElementFromNextRightSibling(p, node, 1); break; case 23: this.TakeElementFromTwoNextRightSibling(p, node, 1); break; case 33: this.TakeElementFromTwoNextRightSibling(p, node, 1); break; } } else if (p.children[2].NumberOfElements() == 0) { //situation can be 0 1 or 3 switch (situation) { case 20: this.TakeElementFromTwoNextLeftSibling(p, node, 2); break; case 30: this.TakeElementFromTwoNextLeftSibling(p, node, 2); break; case 21: this.TakeElementFromNextLeftSibling(p, node, 1); break; case 31: this.TakeElementFromNextLeftSibling(p, node, 1); break; case 23: this.TakeElementFromNextRightSibling(p, node, 2); break; case 33: this.TakeElementFromNextRightSibling(p, node, 2); break; } } else { //situation can be 0 1 or 2 switch (situation) { case 20: this.TakeElementFromThreeNextLeftSibling(p, node); break; case 30: this.TakeElementFromThreeNextLeftSibling(p, node); break; case 21: this.TakeElementFromTwoNextLeftSibling(p, node, 3); break; case 31: this.TakeElementFromTwoNextLeftSibling(p, node, 3); break; case 22: this.TakeElementFromNextLeftSibling(p, node, 2); break; case 32: this.TakeElementFromNextLeftSibling(p, node, 2); break; } } } }