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()); } }
//Tries to insert the elements, if not returns false public bool TryInsert(TreeNode treeNode, int element) { bool result = true; //If it is root just add the element to the root if (treeNode.NumberOfElements() == 0 && treeNode.parent == null) { treeNode.elements[0] = element; } else if (treeNode.NumberOfElements() < this.limit) { treeNode.elements[treeNode.NumberOfElements()] = element; this.SortElements(treeNode.elements, treeNode.NumberOfElements()); } else { result = false; } return result; }
public TreeNode parent; //parent node #endregion Fields #region Constructors //in case this node isn't a leaf, numberOfElement + 1 gives the number of children public TreeNode() { this.parent = null; }
public void TakeElementFromNextRightSibling(TreeNode p, TreeNode node, int n) { node.elements[0] = p.elements[n]; p.elements[n] = p.children[n + 1].elements[0]; if (this.limit == 2) { p.children[n + 1].elements[0] = p.children[n + 1].elements[1]; p.children[n + 1].elements[1] = 0; } else { p.children[n + 1].elements[0] = p.children[n + 1].elements[1]; p.children[n + 1].elements[1] = p.children[n + 1].elements[2]; p.children[n + 1].elements[2] = 0; } if (node.IsLeaf() == false) { node.children[1] = p.children[n + 1].children[0]; if (this.limit == 2) { p.children[n + 1].children[0] = p.children[n + 1].children[1]; p.children[n + 1].children[1] = p.children[n + 1].children[2]; p.children[n + 1].children[2] = null; } else { p.children[n + 1].children[0] = p.children[n + 1].children[1]; p.children[n + 1].children[1] = p.children[n + 1].children[2]; p.children[n + 1].children[2] = p.children[n + 1].children[3]; p.children[n + 1].children[3] = null; } node.children[1].parent = node; } }
public void TakeElementFromTwoNextRightSibling(TreeNode p, TreeNode node, int n) { node.elements[0] = p.elements[n]; p.elements[n] = p.children[n + 1].elements[0]; p.children[n + 1].elements[0] = p.elements[n + 1]; p.elements[n + 1] = p.children[n + 2].elements[0]; if (p.children[n + 2].NumberOfElements() == 2) { p.children[n + 2].elements[0] = p.children[n + 2].elements[1]; p.children[n + 2].elements[1] = 0; } else if (p.children[n + 2].NumberOfElements() == 3) { p.children[n + 2].elements[0] = p.children[n + 2].elements[1]; p.children[n + 2].elements[1] = p.children[n + 2].elements[2]; p.children[n + 2].elements[2] = 0; } if (node.IsLeaf() == false) { node.children[1] = p.children[n + 1].children[0]; p.children[n + 1].children[0] = p.children[n + 1].children[1]; p.children[n + 1].children[1] = p.children[n + 2].children[0]; if (p.children[n + 2].NumberOfElements() == 1) { p.children[n + 2].children[0] = p.children[n + 2].children[1]; p.children[n + 2].children[1] = p.children[n + 2].children[2]; p.children[n + 2].children[2] = null; } else if (p.children[n + 2].NumberOfElements() == 2) { p.children[n + 2].children[0] = p.children[n + 2].children[1]; p.children[n + 2].children[1] = p.children[n + 2].children[2]; p.children[n + 2].children[2] = p.children[n + 2].children[3]; p.children[n + 2].children[3] = null; } node.children[1].parent = node; p.children[n + 1].children[1].parent = p.children[n + 1]; } }
public void Merge(TreeNode node) { if (node.parent.NumberOfElements() == 1) { //empty node at the left if (node.parent.children[0] == node) { node.parent.children[1].elements[1] = node.parent.children[1].elements[0]; node.parent.children[1].elements[0] = node.parent.elements[0]; node.parent.elements[0] = 0; //remove the node node.parent.children[0] = node.parent.children[1]; node.parent.children[1] = null; //if node is internal if (node.IsLeaf() == false) { node.parent.children[0].children[2] = node.parent.children[0].children[1]; node.parent.children[0].children[1] = node.parent.children[0].children[0]; node.parent.children[0].children[0] = node.children[0]; //update the parent node.parent.children[0].children[0].parent = node.parent.children[0]; } } //empty node at the right else { node.parent.children[0].elements[1] = node.parent.elements[0]; node.parent.elements[0] = 0; node.parent.children[1] = null; //if node is internal if (node.IsLeaf() == false) { node.parent.children[0].children[2] = node.children[0]; node.parent.children[0].children[2].parent = node.parent.children[0]; } } } else if (node.parent.NumberOfElements() == 2) { //empty node at the left if (node.parent.children[0] == node) { node.parent.children[1].elements[1] = node.parent.children[1].elements[0]; node.parent.children[1].elements[0] = node.parent.elements[0]; node.parent.elements[0] = node.parent.elements[1]; node.parent.elements[1] = 0; node.parent.children[0] = node.parent.children[1]; node.parent.children[1] = node.parent.children[2]; node.parent.children[2] = null; //if node is internal if (node.IsLeaf() == false) { node.parent.children[0].children[2] = node.parent.children[0].children[1]; node.parent.children[0].children[1] = node.parent.children[0].children[0]; node.parent.children[0].children[0] = node.children[0]; node.parent.children[0].children[0].parent = node.parent.children[0]; } } //empty node at the middle else if (node.parent.children[1] == node) { node.parent.children[0].elements[1] = node.parent.elements[0]; node.parent.elements[0] = node.parent.elements[1]; node.parent.elements[1] = 0; node.parent.children[1] = node.parent.children[2]; node.parent.children[2] = null; //if node is internal if (node.IsLeaf() == false) { node.parent.children[0].children[2] = node.children[0]; node.parent.children[0].children[2].parent = node.parent.children[0]; } } //empty node at the right else { node.parent.children[1].elements[1] = node.parent.elements[1]; node.parent.elements[1] = 0; node.parent.children[2] = null; //if node is internal if (node.IsLeaf() == false) { node.parent.children[1].children[2] = node.children[0]; node.parent.children[1].children[2].parent = node.parent.children[1]; } } } else if (node.parent.NumberOfElements() == 3) { if (node.parent.children[0] == node) { node.parent.children[1].elements[1] = node.parent.children[1].elements[0]; node.parent.children[1].elements[0] = node.parent.elements[0]; node.parent.elements[0] = node.parent.elements[1]; node.parent.elements[1] = node.parent.elements[2]; node.parent.elements[2] = 0; node.parent.children[0] = node.parent.children[1]; node.parent.children[1] = node.parent.children[2]; node.parent.children[2] = node.parent.children[3]; node.parent.children[3] = null; //if node is internal if (node.IsLeaf() == false) { node.parent.children[0].children[2] = node.parent.children[0].children[1]; node.parent.children[0].children[1] = node.parent.children[0].children[0]; node.parent.children[0].children[0] = node.children[0]; node.parent.children[0].children[0].parent = node.parent.children[0]; } } else if (node.parent.children[1] == node) { node.parent.children[0].elements[1] = node.parent.elements[0]; node.parent.elements[0] = node.parent.elements[1]; node.parent.elements[1] = node.parent.elements[2]; node.parent.elements[2] = 0; node.parent.children[1] = node.parent.children[2]; node.parent.children[2] = node.parent.children[3]; node.parent.children[3] = null; //if node is internal if (node.IsLeaf() == false) { node.parent.children[0].children[2] = node.children[0]; node.parent.children[0].children[2].parent = node.parent.children[0]; } } else if (node.parent.children[2] == node) { node.parent.children[1].elements[1] = node.parent.elements[1]; node.parent.elements[1] = node.parent.elements[2]; node.parent.elements[2]= 0; node.parent.children[2] = node.parent.children[3]; node.parent.children[3] = null; //if node is internal if (node.IsLeaf() == false) { node.parent.children[1].children[2] = node.children[0]; node.parent.children[1].children[2].parent = node.parent.children[1]; } } else if (node.parent.children[3] == node) { node.parent.children[2].elements[1] = node.parent.elements[2]; node.parent.elements[2] = 0; node.parent.children[3] = null; //if node is internal if (node.IsLeaf() == false) { node.parent.children[2].children[2] = node.children[0]; node.parent.children[2].children[2].parent = node.parent.children[2]; } } } }
public virtual void Split(TreeNode treeNode, int element) { Console.WriteLine("This method should be overrided"); }
public TreeNode InOrderSuccessor(int element, TreeNode node) { TreeNode next; // When this method is called, key will equal smallValue or largeValue, and we must do a comparison. // We check if location is a three node and, if it is, we compare key to smallValue. If equal, go down middleChild. if (node.children[0] != null && node.children[1] != null && node.children[2] != null && node.children[3] != null) { if (node.elements[0] == element) { next = node.children[1]; } else if (node.elements[1] == element) { next = node.children[2]; } else { next = node.children[3]; } } else if (node.children[0] != null && node.children[1] != null && node.children[2] != null) { if (node.elements[0] == element) { next = node.children[1]; } else { next = node.children[2]; } } else { next = node.children[1]; } // Continue down left branches until we encounter a leaf. while (next.IsLeaf() == false) { next = next.children[0]; } return next; }
//Look for the right or the closest siblings with two or three elements, if not returns -1 public int HasChildWithTwoElement(TreeNode node) { int result = -1; //check the number of the children equality to 2 if (node.NumberOfElements() == 1) { for (int i = 0; i < node.children.Length; i++) { if (node.children[i] != null) { if (node.children[i].NumberOfElements() == 2 || node.children[i].NumberOfElements() == 3) { result = i; result = result + node.children[i].NumberOfElements() * 10; break; } } } } //number of the children equality to 3 else if (node.NumberOfElements() == 2) { if (node.children[0].NumberOfElements() == 0) { for (int i = 0; i < node.children.Length; i++) { if (node.children[i] != null) { if (node.children[i].NumberOfElements() == 2 || node.children[i].NumberOfElements() == 3) { result = i; result = result + node.children[i].NumberOfElements() * 10; break; } } } } // I should take from the right first so the loop counter is decreasing else { for (int i = node.children.Length - 1; i >= 0; i--) { if (node.children[i] != null) { if (node.children[i].NumberOfElements() == 2 || node.children[i].NumberOfElements() == 3) { result = i; result = result + node.children[i].NumberOfElements() * 10; break; } } } } } //number of the children equality to 4 else if (node.NumberOfElements() == 3) { if (node.children[0].NumberOfElements() == 0) { for (int i = 0; i < node.children.Length; i++) { if (node.children[i] != null) { if (node.children[i].NumberOfElements() == 2 || node.children[i].NumberOfElements() == 3) { result = i; result = result + node.children[i].NumberOfElements() * 10; break; } } } } // I should take from the right first so the loop counter is decreasing else { if (node.children[1].NumberOfElements() == 0) { //Check for the element at the right first for (int i = 1; i < node.children.Length; i++) { if (node.children[i] != null) { if (node.children[i].NumberOfElements() == 2 || node.children[i].NumberOfElements() == 3) { result = i; result = result + node.children[i].NumberOfElements() * 10; break; } } } //If doesn't exist in the right look left if (result == -1) { if (node.children[0].NumberOfElements() == 2 || node.children[0].NumberOfElements() == 3) { result = node.children[0].NumberOfElements() * 10; } } } else { for (int i = node.children.Length - 1; i >= 0; i--) { if (node.children[i] != null) { if (node.children[i].NumberOfElements() == 2 || node.children[i].NumberOfElements() == 3) { result = i; result = result + node.children[i].NumberOfElements() * 10; break; } } } } } } return result; }
public TreeNode FindSubtreeLeaf(TreeNode node, int element) { if (node.IsLeaf()) return node; else { if (element < node.elements[0]) return this.FindSubtreeLeaf(node.children[0], element); else if (node.NumberOfElements() == 1 || (element > node.elements[0] && element < node.elements[1])) return this.FindSubtreeLeaf(node.children[1], element); else if (node.NumberOfElements() == 2 || (element > node.elements[1] && element < node.elements[2])) return this.FindSubtreeLeaf(node.children[2], element); else return this.FindSubtreeLeaf(node.children[3], element); } }
//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; } }
public TreeNode FindNode(TreeNode node, int element) { bool isFound = false; if (node != null) { for (int i = 0; i < node.NumberOfElements(); i++) { if (node.elements[i] == element) isFound = true; } if (isFound == true) return node; else if (node.NumberOfElements() == 1) { if (element < node.elements[0]) return FindNode(node.children[0], element); else return FindNode(node.children[1], element); } else if (node.NumberOfElements() == 2) { if (element < node.elements[0]) { return FindNode(node.children[0], element); } else if (element > node.elements[1]) { return FindNode(node.children[2], element); } else { return FindNode(node.children[1], element); } } else if (node.NumberOfElements() == 3) { if (element < node.elements[0]) { return FindNode(node.children[0], element); } else if (element > node.elements[0] && element < node.elements[1]) { return FindNode(node.children[1], element); } else if (element > node.elements[1] && element < node.elements[2]) { return FindNode(node.children[2], element); } else { return FindNode(node.children[3], element); } } } return null; }