void Redistrubute(TwoThreeTreeNode node, TwoThreeTreeNode p, int situation) { //there is two different situation if the parent has two nodes if (p.NumberOfElements() == 1) { if (situation == 20) { 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) { 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) { 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) { this.TakeElementFromTwoNextLeftSibling(p, node, 2); } else { this.TakeElementFromNextLeftSibling(p, node, 1); } } } }
public void Delete(int element) { TwoThreeTreeNode shouldFixed = (TwoThreeTreeNode)this.DeleteElement(element); if (shouldFixed != null) { Fix(shouldFixed); } }
public void Fix(TwoThreeTreeNode node) { TwoThreeTreeNode p; if (node.parent == null) { if (node.children[0] == null) { return; } root = node.children[0]; root.parent = null; } else { p = (TwoThreeTreeNode)node.parent; int situation = HasChildWithTwoElement(p); if (situation > -1) { Redistrubute(node, p, situation); } else { Merge(node); } if (node.parent.NumberOfElements() == 0) { Fix((TwoThreeTreeNode)node.parent); } } }
void Redistrubute(TwoThreeTreeNode node, TwoThreeTreeNode p, int situation) { //there is two different situation if the parent has two nodes if (p.NumberOfElements() == 1) { if (situation == 20) { 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) { 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) { 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) { this.TakeElementFromTwoNextLeftSibling(p, node, 2); } else { this.TakeElementFromNextLeftSibling(p, node, 1); } } } }
//Recursively split to balance the tree public override void Split(TreeNode twoThreeNode, int element) { TwoThreeTreeNode p; if (twoThreeNode.parent == null) { p = new TwoThreeTreeNode(); } else { p = (TwoThreeTreeNode) twoThreeNode.parent; } TwoThreeTreeNode n1 = new TwoThreeTreeNode(); TwoThreeTreeNode n2 = new TwoThreeTreeNode(); //finding the smallest, middle and large elements int small, middle, large; if (element < twoThreeNode.elements[0]) { small = element; middle = twoThreeNode.elements[0]; large = twoThreeNode.elements[1]; } else if (element > twoThreeNode.elements[1]) { small = twoThreeNode.elements[0]; middle = twoThreeNode.elements[1]; large = element; } else { small = twoThreeNode.elements[0]; middle = element; large = twoThreeNode.elements[1]; } //set smallest and largest keys to the n1 and n2 respectively n1.elements[0] = small; n2.elements[0] = large; //Make p the parent node of n1 and n2 n1.parent = p; n2.parent = p; if (p.NumberOfElements() == 0) { p.children[0] = n1; p.children[1] = n2; this.root = p; n1.isLeaf = true; n2.isLeaf = true; } 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; } n1.isLeaf = true; n2.isLeaf = true; } else { 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[0] > p.elements[0] && n1.elements[0] > 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; } } //if it is not a leaf check if (twoThreeNode.IsLeaf() == false) { twoThreeNode.children[0].parent = n1; twoThreeNode.children[1].parent = n1; twoThreeNode.children[2].parent = n2; twoThreeNode.children[3].parent = n2; n1.children[0] = twoThreeNode.children[0]; n1.children[1] = twoThreeNode.children[1]; n2.children[0] = twoThreeNode.children[2]; n2.children[1] = twoThreeNode.children[3]; n1.isLeaf = false; n2.isLeaf = false; } if (p.NumberOfElements() == 2) { this.Split(p, middle); if (n1.children[0] != null || n2.children[0] != null) { if (n1.children[0].IsLeaf() || n2.children[0].IsLeaf()) { n1.isLeaf = false; n2.isLeaf = false; } } else { n1.isLeaf = true; n2.isLeaf = true; } n1.parent.isLeaf = false; n2.parent.isLeaf = false; } else if (p.NumberOfElements() == 1) { if (p.elements[0] < middle) { p.elements[1] = middle; } else { p.elements[1] = p.elements[0]; p.elements[0] = middle; } } else { p.elements[0] = middle; } }
//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(TwoThreeTreeNode node) { TwoThreeTreeNode 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; //this.root.children[2] = node.children[2]; } else { p = (TwoThreeTreeNode) 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( (TwoThreeTreeNode) node.parent); } } }
public override void Split(TreeNode twoThreeNode, int element) { TwoThreeTreeNode p; if (twoThreeNode.parent == null) { p = new TwoThreeTreeNode(); } else { p = (TwoThreeTreeNode)twoThreeNode.parent; } TwoThreeTreeNode n1 = new TwoThreeTreeNode(); TwoThreeTreeNode n2 = new TwoThreeTreeNode(); int small, middle, large; if (element < twoThreeNode.elements[0]) { small = element; middle = twoThreeNode.elements[0]; large = twoThreeNode.elements[1]; } else if (element > twoThreeNode.elements[1]) { small = twoThreeNode.elements[0]; middle = twoThreeNode.elements[1]; large = element; } else { small = twoThreeNode.elements[0]; middle = element; large = twoThreeNode.elements[1]; } n1.elements[0] = small; n2.elements[0] = large; n1.parent = p; n2.parent = p; if (p.NumberOfElements() == 0) { p.children[0] = n1; p.children[1] = n2; root = p; n1.isLeaf = true; n2.isLeaf = true; } 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; } n1.isLeaf = true; n2.isLeaf = true; } else { 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[0] > p.elements[0] && n1.elements[0] > 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; } } if (twoThreeNode.IsLeaf() == false) { twoThreeNode.children[0].parent = n1; twoThreeNode.children[1].parent = n1; twoThreeNode.children[2].parent = n2; twoThreeNode.children[3].parent = n2; n1.children[0] = twoThreeNode.children[0]; n1.children[1] = twoThreeNode.children[1]; n2.children[0] = twoThreeNode.children[2]; n2.children[1] = twoThreeNode.children[3]; n1.isLeaf = false; n2.isLeaf = false; } if (p.NumberOfElements() == 2) { Split(p, middle); if (n1.children[0] != null || n2.children[0] != null) { if (n1.children[0].IsLeaf() || n2.children[0].IsLeaf()) { n1.isLeaf = false; n2.isLeaf = false; } } else { n1.isLeaf = true; n2.isLeaf = true; } n1.parent.isLeaf = false; n2.parent.isLeaf = false; } else if (p.NumberOfElements() == 1) { if (p.elements[0] < middle) { p.elements[1] = middle; } else { p.elements[1] = p.elements[0]; p.elements[0] = middle; } } else { p.elements[0] = middle; } }
public TwoThreeTree() { root = new TwoThreeTreeNode(); limit = 2; initRoot(); }
public TwoThreeTreeNode() { elements = new int[2]; children = new TwoThreeTreeNode[4]; }