private void InsertIntoTree(int value) { int currentLevel = 0; RBTreeNode node = root; while (node != null) { currentLevel++; if (value < node.value) { if (node.leftNode == null) { if (currentLevel > level) { level = currentLevel; } node.leftNode = newNode; FixParent(node.leftNode, node); break; } else { node = node.leftNode; } } else { if (node.rightNode == null) { if (currentLevel > level) { level = currentLevel; } node.rightNode = newNode; FixParent(node.rightNode, node); break; } else { node = node.rightNode; } } } }
private RBTreeNode FindValue(int value) { RBTreeNode node = root; while (node != null) { if (value == node.value) { break; } if (value < node.value) { node = node.leftNode; } else { node = node.rightNode; } } return(node); }
public void RemoveElement(int value) { stepsForm.AddStep("Briše se čvor s vrijednošću " + value + "."); Boolean replaceColorIsRed = RemoveFromTree(value); if (deleteChild == null) { return; } if (root == null) { return; } if (deleteChild == null || replaceColorIsRed == true) { if (deleteChild != null && deleteChild.isNullLeaf) { if (deleteChild.parentNode.leftNode == deleteChild) { deleteChild.parentNode.leftNode = null; } else { deleteChild.parentNode.rightNode = null; } deleteChild = null; } return; } while (deleteChild != root && !deleteChild.isRed) { stepsForm.AddSubStep(string.Format("Dijete N {0} je crne boje.", deleteChild)); if (deleteChild == deleteChild.parentNode.leftNode) { stepsForm.AddSubStep(string.Format("N {0} je lijevo dijete roditelja P {1}.", deleteChild, deleteChild.parentNode)); RBTreeNode sibling = deleteChild.parentNode.rightNode; if (sibling.isRed) { stepsForm.AddSubStep(string.Format("S {0}, drugo dijete od P {1} je crvene boje, boji se u crnu.", sibling, deleteChild.parentNode)); sibling.isRed = false; stepsForm.AddSubStep(string.Format("Roditelj od N P {0} se boji u crvenu.", deleteChild.parentNode)); deleteChild.parentNode.isRed = true; stepsForm.AddSubStep(string.Format("Obavlja se lijeva rotacija S {0} oko P {1}.", sibling, deleteChild.parentNode)); deleteChild.parentNode.rightNode = sibling.leftNode; sibling.leftNode.parentNode = deleteChild.parentNode; sibling.leftNode = deleteChild.parentNode; if (deleteChild.parentNode == root) { root = sibling; sibling.parentNode = null; } else { if (deleteChild.parentNode == deleteChild.parentNode.parentNode.leftNode) { deleteChild.parentNode.parentNode.leftNode = sibling; } else { deleteChild.parentNode.parentNode.rightNode = sibling; } sibling.parentNode = deleteChild.parentNode.parentNode; } deleteChild.parentNode.parentNode = sibling; } sibling = deleteChild.parentNode.rightNode; if ((sibling.leftNode == null || !sibling.leftNode.isRed) && (sibling.rightNode == null || !sibling.rightNode.isRed)) { stepsForm.AddSubStep(string.Format("Djeca od S {0} su crna. S {0} se boji u crvenu.", sibling)); sibling.isRed = true; if (deleteChild.isNullLeaf) { if (deleteChild.parentNode.leftNode == deleteChild) { deleteChild.parentNode.leftNode = null; } else { deleteChild.parentNode.rightNode = null; } } stepsForm.AddSubStep(string.Format("Roditelj od N P {0} postaje novi N.", deleteChild.parentNode)); deleteChild = deleteChild.parentNode; } else { if (sibling.rightNode == null || !sibling.rightNode.isRed) { stepsForm.AddSubStep(string.Format("Desno dijete od S SR {0} je crne boje. Lijevo dijete od S SL {1} se boji u crnu.", sibling.rightNode, sibling.leftNode)); sibling.leftNode.isRed = false; stepsForm.AddSubStep(string.Format("S {0} se boji u crvenu.", sibling)); sibling.isRed = true; stepsForm.AddSubStep(string.Format("Obavlja se desna rotacija SL {0} oko S {1}.", sibling.leftNode, sibling)); deleteChild.parentNode.rightNode = sibling.leftNode; sibling.leftNode.parentNode = deleteChild.parentNode; sibling.leftNode = sibling.leftNode.rightNode; FixParent(sibling.leftNode, sibling); deleteChild.parentNode.rightNode.rightNode = sibling; sibling.parentNode = deleteChild.parentNode.rightNode; } sibling = deleteChild.parentNode.rightNode; stepsForm.AddSubStep(string.Format("S {0} se boji u boju od roditelja P {1}.", sibling, deleteChild.parentNode)); sibling.isRed = deleteChild.parentNode.isRed; stepsForm.AddSubStep(string.Format("P {0} se boji u crnu.", deleteChild.parentNode)); deleteChild.parentNode.isRed = false; stepsForm.AddSubStep(string.Format("Desno dijete od S SR {0} se boji u crnu.", sibling.rightNode)); if (sibling.rightNode != null) { sibling.rightNode.isRed = false; } stepsForm.AddSubStep(string.Format("Obavlja se lijeva rotacija S {0} oko P {1}.", sibling, deleteChild.parentNode)); deleteChild.parentNode.rightNode = sibling.leftNode; FixParent(deleteChild.parentNode.rightNode, deleteChild.parentNode); if (deleteChild.parentNode == root) { root = sibling; sibling.parentNode = null; } else { if (deleteChild.parentNode == deleteChild.parentNode.parentNode.leftNode) { deleteChild.parentNode.parentNode.leftNode = sibling; } else { deleteChild.parentNode.parentNode.rightNode = sibling; } sibling.parentNode = deleteChild.parentNode.parentNode; } sibling.leftNode = deleteChild.parentNode; deleteChild.parentNode.parentNode = sibling; stepsForm.AddSubStep(string.Format("Korijen {0} postaje novi N.", root)); if (deleteChild.isNullLeaf) { if (deleteChild.parentNode.leftNode == deleteChild) { deleteChild.parentNode.leftNode = null; } else { deleteChild.parentNode.rightNode = null; } } deleteChild = root; } } else { stepsForm.AddSubStep(string.Format("N {0} je desno dijete roditelja P {1}.", deleteChild, deleteChild.parentNode)); RBTreeNode sibling = deleteChild.parentNode.leftNode; if (sibling.isRed) { stepsForm.AddSubStep(string.Format("S {0}, drugo dijete od P {1} je crvene boje, boji se u crnu.", sibling, deleteChild.parentNode)); sibling.isRed = false; stepsForm.AddSubStep(string.Format("Roditelj od N P {0} se boji u crvenu.", deleteChild.parentNode)); deleteChild.parentNode.isRed = true; stepsForm.AddSubStep(string.Format("Obavlja se desna rotacija S {0} oko P {1}.", sibling, deleteChild.parentNode)); deleteChild.parentNode.leftNode = sibling.rightNode; sibling.rightNode.parentNode = deleteChild.parentNode; sibling.rightNode = deleteChild.parentNode; if (deleteChild.parentNode == root) { root = sibling; sibling.parentNode = null; } else { if (deleteChild.parentNode == deleteChild.parentNode.parentNode.rightNode) { deleteChild.parentNode.parentNode.rightNode = sibling; } else { deleteChild.parentNode.parentNode.leftNode = sibling; } sibling.parentNode = deleteChild.parentNode.parentNode; } deleteChild.parentNode.parentNode = sibling; } sibling = deleteChild.parentNode.leftNode; if ((sibling.leftNode == null || !sibling.leftNode.isRed) && (sibling.rightNode == null || !sibling.rightNode.isRed)) { stepsForm.AddSubStep(string.Format("Djeca od S {0} su crna. S {0} se boji u crvenu.", sibling)); sibling.isRed = true; if (deleteChild.isNullLeaf) { if (deleteChild.parentNode.leftNode == deleteChild) { deleteChild.parentNode.leftNode = null; } else { deleteChild.parentNode.rightNode = null; } } stepsForm.AddSubStep(string.Format("Roditelj od N P {0} postaje novi N.", deleteChild.parentNode)); deleteChild = deleteChild.parentNode; } else { if (sibling.leftNode == null || !sibling.leftNode.isRed) { stepsForm.AddSubStep(string.Format("Lijevo dijete od S SL {0} je crne boje. Desno dijete od S SR {1} se boji u crnu.", sibling.leftNode, sibling.rightNode)); sibling.rightNode.isRed = false; stepsForm.AddSubStep(string.Format("S {0} se boji u crvenu.", sibling)); sibling.isRed = true; stepsForm.AddSubStep(string.Format("Obavlja se lijeva rotacija SR {0} oko S {1}.", sibling.rightNode, sibling)); deleteChild.parentNode.leftNode = sibling.rightNode; FixParent(deleteChild.parentNode.leftNode, deleteChild.parentNode); sibling.rightNode = sibling.rightNode.leftNode; FixParent(sibling.rightNode, sibling); deleteChild.parentNode.leftNode.leftNode = sibling; sibling.parentNode = deleteChild.parentNode.leftNode; } sibling = deleteChild.parentNode.leftNode; stepsForm.AddSubStep(string.Format("S {0} se boji u boju od roditelja P {1}.", sibling, deleteChild.parentNode)); sibling.isRed = deleteChild.parentNode.isRed; stepsForm.AddSubStep(string.Format("P {0} se boji u crnu.", deleteChild.parentNode)); deleteChild.parentNode.isRed = false; stepsForm.AddSubStep(string.Format("Lijevo dijete od S SL {0} se boji u crnu.", sibling.leftNode)); if (sibling.leftNode != null) { sibling.leftNode.isRed = false; } stepsForm.AddSubStep(string.Format("Obavlja se desna rotacija S {0} oko P {1}.", sibling, deleteChild.parentNode)); deleteChild.parentNode.leftNode = sibling.rightNode; FixParent(deleteChild.parentNode.leftNode, deleteChild.parentNode); if (deleteChild.parentNode == root) { root = sibling; sibling.parentNode = null; } else { if (deleteChild.parentNode == deleteChild.parentNode.parentNode.rightNode) { deleteChild.parentNode.parentNode.rightNode = sibling; } else { deleteChild.parentNode.parentNode.leftNode = sibling; } sibling.parentNode = deleteChild.parentNode.parentNode; } sibling.rightNode = deleteChild.parentNode; deleteChild.parentNode.parentNode = sibling; stepsForm.AddSubStep(string.Format("Korijen {0} postaje novi N.", root)); if (deleteChild.isNullLeaf) { if (deleteChild.parentNode.rightNode == deleteChild) { deleteChild.parentNode.rightNode = null; } else { deleteChild.parentNode.leftNode = null; } } deleteChild = root; } } } stepsForm.AddSubStep(string.Format("N {0} se boji u crnu.", deleteChild)); deleteChild.isRed = false; }
public void AddElement(int value) { if (value.ToString().Length + 2 > RBTree.defaultPrintNodeLength) { int newLength = value.ToString().Length + 2; if (newLength % 2 == 1) { newLength += 1; } RBTree.defaultPrintNodeLength = newLength; } newNode = new RBTreeNode(value, true); stepsForm.AddStep("Dodaje se novi čvor N crvene boje: " + newNode + "."); if (root == null) { root = newNode; stepsForm.AddSubStep(string.Format("Novi čvor N {0} je korijen stabla, boja mu se mijenja u crnu.", newNode)); root.isRed = false; } else { InsertIntoTree(value); RBTreeNode parent = newNode.parentNode; if (!parent.isRed) { stepsForm.AddSubStep("Roditelj P " + parent + " je crne boje. Nema potrebe za rekonstrukcijom."); } while (newNode.parentNode != null && newNode.parentNode.isRed) { stepsForm.AddSubStep(string.Format("Roditelj P {0} je crvene boje.", newNode.parentNode)); RBTreeNode grandparent = newNode.parentNode.parentNode; RBTreeNode uncle; // p(N) == g(N).left if (newNode.parentNode == newNode.parentNode.parentNode.leftNode) { uncle = newNode.parentNode.parentNode.rightNode; stepsForm.AddSubStep(string.Format("P {0} je lijevo dijete od djeda G {1}. " + "Ujak U {2} je desno dijete od G {1}.", newNode.parentNode, newNode.parentNode.parentNode, uncle)); if (uncle != null && uncle.isRed) { stepsForm.AddSubStep(string.Format("U {0} je crven. P {1} postaje crn, " + "U {0} postaje crn, G {2} postaje crven.", uncle, newNode.parentNode, newNode.parentNode.parentNode)); newNode.parentNode.isRed = false; uncle.isRed = false; newNode.parentNode.parentNode.isRed = true; newNode = newNode.parentNode.parentNode; } else { parent = newNode.parentNode; grandparent = parent.parentNode; stepsForm.AddSubStep(string.Format("U {0} je crn.", uncle)); if (newNode == parent.rightNode) { stepsForm.AddSubStep(string.Format("Novi čvor N {0} je desno dijete od P {1}. " + "Obavlja se lijeva rotacija N {0} oko P {1}.", newNode, parent)); grandparent.leftNode = newNode; FixParent(grandparent.leftNode, grandparent); parent.rightNode = newNode.leftNode; FixParent(parent.rightNode, parent); newNode.leftNode = parent; FixParent(newNode.leftNode, newNode); stepsForm.AddSubStep(string.Format("N {0} postaje P {1}.", newNode, parent)); newNode = parent; } RBTreeNode tempParent = newNode.parentNode; RBTreeNode tempGrandparent = tempParent.parentNode; RBTreeNode tempGrandGrandparent = tempGrandparent.parentNode; stepsForm.AddSubStep(string.Format("Obavlja se desna rotacija roditelja od N p(N) {0} oko djeda od N g(N) {1}.", tempParent, tempGrandparent)); Rotation(newNode.parentNode, newNode.parentNode.parentNode, true); stepsForm.AddSubStep(string.Format("P {0} postaje crn, G {1} postaje crven.", newNode.parentNode, newNode.parentNode.parentNode)); if (newNode.parentNode != null) { newNode.parentNode.isRed = false; } newNode.parentNode.parentNode.isRed = true; } } else { uncle = newNode.parentNode.parentNode.leftNode; stepsForm.AddSubStep(string.Format("P {0} je desno dijete od djeda G {1}. Ujak U {2} je lijevo dijete od G {1}.", parent, grandparent, uncle)); if (uncle != null && uncle.isRed) { stepsForm.AddSubStep(string.Format("U {0} je crven. P {1} postaje crn, U {0} postaje crn, G {2} postaje crven.", uncle, newNode.parentNode, newNode.parentNode.parentNode)); newNode.parentNode.isRed = false; uncle.isRed = false; newNode.parentNode.parentNode.isRed = true; newNode = newNode.parentNode.parentNode; } else { parent = newNode.parentNode; grandparent = parent.parentNode; stepsForm.AddSubStep(string.Format("U {0} je crn.", uncle)); if (newNode == parent.leftNode) { stepsForm.AddSubStep(string.Format("Novi čvor N {0} je lijevo dijete od P {1}. Obavlja se desna rotacija N {0} oko P {1}.", newNode, parent)); grandparent.rightNode = newNode; FixParent(grandparent.rightNode, grandparent); parent.leftNode = newNode.rightNode; FixParent(parent.leftNode, parent); newNode.rightNode = parent; FixParent(newNode.rightNode, newNode); stepsForm.AddSubStep(string.Format("N {0} postaje P {1}.", newNode, parent)); newNode = parent; } RBTreeNode tempParent = newNode.parentNode; RBTreeNode tempGrandparent = tempParent.parentNode; RBTreeNode tempGrandGrandparent = tempGrandparent.parentNode; stepsForm.AddSubStep(string.Format("Obavlja se lijeva rotacija roditelja od N p(N) {0} oko djeda od N g(N) {1}.", tempParent, tempGrandparent)); Rotation(newNode.parentNode, newNode.parentNode.parentNode, false); stepsForm.AddSubStep(string.Format("P {0} postaje crn, G {1} postaje crven.", newNode.parentNode, newNode.parentNode.parentNode)); if (newNode.parentNode != null) { newNode.parentNode.isRed = false; } grandparent.isRed = true; } } } RBTreeNode node = parent; while (node.parentNode != null) { node = node.parentNode; } if (node.isRed) { stepsForm.AddSubStep(string.Format("Korijen {0} postaje crn.", root)); node.isRed = false; } } }
public void Reset() { root = null; newNode = null; level = 0; }
private Boolean RemoveFromTree(int value) { RBTreeNode deleteNode = FindValue(value); if (deleteNode == null) { return(false); } if (deleteNode == root && deleteNode.leftNode == null && deleteNode.rightNode == null) { root = null; return(false); } deleteChild = null; if (deleteNode == null) { return(true); } RBTreeNode replaceNode = FindReplace(deleteNode); Boolean replaceColor = replaceNode.isRed; if (replaceNode == deleteNode) { // delnode != root if (deleteNode.parentNode != null) { deleteChild = new RBTreeNode(-1, false); deleteChild.isNullLeaf = true; deleteChild.parentNode = deleteNode.parentNode; if (deleteNode.parentNode.leftNode == deleteNode) { deleteNode.parentNode.leftNode = deleteChild; } else { deleteNode.parentNode.rightNode = deleteChild; } } deleteNode = null; return(replaceColor); } if (replaceNode.value <= deleteNode.value) { if (deleteNode.leftNode == replaceNode) { deleteNode.leftNode = replaceNode.leftNode; if (deleteNode.leftNode != null) { deleteNode.leftNode.parentNode = deleteNode; deleteChild = deleteNode.leftNode; } else { deleteChild = new RBTreeNode(-1, false); deleteChild.isNullLeaf = true; deleteNode.leftNode = deleteChild; } deleteChild.parentNode = deleteNode; deleteNode.value = replaceNode.value; replaceNode = null; } else { RBTreeNode parentOfReplace = replaceNode.parentNode; parentOfReplace.rightNode = replaceNode.leftNode; if (parentOfReplace.rightNode == null) { deleteChild = new RBTreeNode(-1, false); deleteChild.isNullLeaf = true; parentOfReplace.rightNode = deleteChild; deleteChild.parentNode = parentOfReplace; } else { if (parentOfReplace.rightNode.leftNode != null) { parentOfReplace.rightNode.leftNode.parentNode = parentOfReplace; deleteChild = parentOfReplace.rightNode.leftNode; } else { deleteChild = new RBTreeNode(-1, false); deleteChild.isNullLeaf = true; parentOfReplace.rightNode.leftNode = deleteChild; deleteChild.parentNode = parentOfReplace; } } deleteNode.value = replaceNode.value; replaceNode = null; } } else { if (deleteNode.rightNode == replaceNode) { deleteNode.rightNode = replaceNode.rightNode; if (deleteNode.rightNode != null) { deleteChild = deleteNode.rightNode; } else { deleteChild = new RBTreeNode(-1, false); deleteChild.isNullLeaf = true; deleteNode.rightNode = deleteChild; } deleteChild.parentNode = deleteNode; deleteNode.value = replaceNode.value; replaceNode = null; } else { RBTreeNode parentOfReplace = replaceNode.parentNode; parentOfReplace.leftNode = replaceNode.rightNode; if (parentOfReplace.leftNode == null) { deleteChild = new RBTreeNode(-1, false); deleteChild.isNullLeaf = true; parentOfReplace.leftNode = deleteChild; deleteChild.parentNode = parentOfReplace; } else { if (parentOfReplace.leftNode.rightNode != null) { parentOfReplace.leftNode.rightNode.parentNode = parentOfReplace; deleteChild = parentOfReplace.leftNode.rightNode; } else { deleteChild = new RBTreeNode(-1, false); deleteChild.isNullLeaf = true; parentOfReplace.leftNode.rightNode = deleteChild; deleteChild.parentNode = parentOfReplace; } } deleteNode.value = replaceNode.value; replaceNode = null; } } return(replaceColor); }
private void Rotation(RBTreeNode rotated, RBTreeNode centered, Boolean leftSide) { RBTreeNode parentCentered = centered.parentNode; // p(N) == root if (parentCentered == null) { if (leftSide) { // g(N).left = p(N).right centered.leftNode = rotated.rightNode; FixParent(centered.leftNode, centered); // p(N).right = g(N) rotated.rightNode = centered; FixParent(rotated.rightNode, rotated); } else { // g(N).right = p(N).left centered.rightNode = rotated.leftNode; FixParent(centered.rightNode, centered); // p(N).left = g(N) rotated.leftNode = centered; FixParent(rotated.leftNode, rotated); } root = rotated; rotated.parentNode = parentCentered; } else if (leftSide) { if (parentCentered.leftNode == centered) { // p(g(N)).left = p(N) parentCentered.leftNode = rotated; FixParent(parentCentered.leftNode, parentCentered); // g(N).left = p(N).right centered.leftNode = rotated.rightNode; FixParent(centered.leftNode, centered); // p(N).right = g(N) rotated.rightNode = centered; FixParent(rotated.rightNode, rotated); } else { // p(g(N)).right = p(N) parentCentered.rightNode = rotated; FixParent(parentCentered.rightNode, parentCentered); // g(N).left = p(N).right centered.leftNode = rotated.rightNode; FixParent(centered.leftNode, centered); // p(N).right = g(N) rotated.rightNode = centered; FixParent(rotated.rightNode, rotated); } } else { if (parentCentered.rightNode == centered) { // p(g(N)).right = p(N) parentCentered.rightNode = rotated; FixParent(parentCentered.rightNode, parentCentered); // g(N).right = p(N).left centered.rightNode = rotated.leftNode; FixParent(centered.rightNode, centered); // p(N).left = g(N) rotated.leftNode = centered; FixParent(rotated.leftNode, rotated); } else { // p(g(N)).left = p(N) parentCentered.leftNode = rotated; FixParent(parentCentered.leftNode, parentCentered); // g(N).right = p(N).left centered.rightNode = rotated.leftNode; FixParent(centered.rightNode, centered); // p(N).left = g(N) rotated.leftNode = centered; FixParent(rotated.leftNode, rotated); } } }