/// <summary> /// Ľavá rotácia podľa prvku. /// </summary> /// <param name="iRBTreeNode">Prvok, podľa ktorého rotujem.</param> private void RotujVLavo(RBTreeNode <TKey, TValue> iRBTreeNode) { // Nastavim sa RBTreeNode <TKey, TValue> rbTreeNode = iRBTreeNode.RightNode; // Otcovi dam ako praveho syna svoj lavy podstrom iRBTreeNode.RightNode = rbTreeNode.LeftNode; if (rbTreeNode.LeftNode != _treeNodeNull) { rbTreeNode.LeftNode.Parent = iRBTreeNode; //presmerujem otca } if (rbTreeNode != _treeNodeNull) { // Nastavim si za otca otca mojho otca rbTreeNode.Parent = iRBTreeNode.Parent; } if (iRBTreeNode.Parent != null) { // Nastavim sa svojnu dedkovy ako pravy, alebo lavy syn if (iRBTreeNode == iRBTreeNode.Parent.LeftNode) { iRBTreeNode.Parent.LeftNode = rbTreeNode; } else { iRBTreeNode.Parent.RightNode = rbTreeNode; } } else { _treeNode = rbTreeNode; } rbTreeNode.LeftNode = iRBTreeNode; if (iRBTreeNode != _treeNodeNull) { iRBTreeNode.Parent = rbTreeNode; } }
/// <summary> /// Pravá rotácia. /// </summary> /// <param name="iRBTreeNode">Prvok, podľa ktorého rotujem.</param> private void RotujVPravo(RBTreeNode <TKey, TValue> iRBTreeNode) { RBTreeNode <TKey, TValue> rbTreeNode = iRBTreeNode.LeftNode; iRBTreeNode.LeftNode = rbTreeNode.RightNode; if (rbTreeNode.RightNode != _treeNodeNull) { rbTreeNode.RightNode.Parent = iRBTreeNode; } if (rbTreeNode != _treeNodeNull) { rbTreeNode.Parent = iRBTreeNode.Parent; } if (iRBTreeNode.Parent != null) { if (iRBTreeNode == iRBTreeNode.Parent.RightNode) { iRBTreeNode.Parent.RightNode = rbTreeNode; } else { iRBTreeNode.Parent.LeftNode = rbTreeNode; } } else { _treeNode = rbTreeNode; } rbTreeNode.RightNode = iRBTreeNode; if (iRBTreeNode != _treeNodeNull) { iRBTreeNode.Parent = rbTreeNode; } }
/// <summary> /// Vyvažovanie stromu podľa novovloženého prvku. /// </summary> /// <param name="iRBTreeNode">Novovložený prvok.</param> private void Reorganizuj(RBTreeNode <TKey, TValue> iRBTreeNode) { RBTreeNode <TKey, TValue> rbTreeNode; // Pokial otec je cerveny (dva cervene zasebou) while (iRBTreeNode != _treeNode && iRBTreeNode.Parent.Color == RBTreeColor.Red) { // Zistim si ci moj otec je lavym, alebo pravym potomkom if (iRBTreeNode.Parent == iRBTreeNode.Parent.Parent.LeftNode) { rbTreeNode = iRBTreeNode.Parent.Parent.RightNode; // Ak brat mojho otca je cerveny if (rbTreeNode != null && rbTreeNode.Color == RBTreeColor.Red) { // Tak prefarbi iRBTreeNode.Parent.Color = RBTreeColor.Black; rbTreeNode.Color = RBTreeColor.Black; iRBTreeNode.Parent.Parent.Color = RBTreeColor.Red; // Kontroluj dalej od dedka iRBTreeNode = iRBTreeNode.Parent.Parent; } else { // Inak rotuj // Ak som pravym synom tak lavo prava rotacia if (iRBTreeNode == iRBTreeNode.Parent.RightNode) { iRBTreeNode = iRBTreeNode.Parent; RotujVLavo(iRBTreeNode); } // Inak len prava iRBTreeNode.Parent.Color = RBTreeColor.Black; iRBTreeNode.Parent.Parent.Color = RBTreeColor.Red; RotujVPravo(iRBTreeNode.Parent.Parent); } } else { rbTreeNode = iRBTreeNode.Parent.Parent.LeftNode; // Ak brat mojho otca je cerveny if (rbTreeNode != null && rbTreeNode.Color == RBTreeColor.Red) { // Tak prefarbi iRBTreeNode.Parent.Color = RBTreeColor.Black; rbTreeNode.Color = RBTreeColor.Black; iRBTreeNode.Parent.Parent.Color = RBTreeColor.Red; iRBTreeNode = iRBTreeNode.Parent.Parent; } else { // Inak rotuj // Ak som lavym synom if (iRBTreeNode == iRBTreeNode.Parent.LeftNode) { //tak najskor rotuj v pravo iRBTreeNode = iRBTreeNode.Parent; RotujVPravo(iRBTreeNode); } // Rotujem vlavo iRBTreeNode.Parent.Color = RBTreeColor.Black; iRBTreeNode.Parent.Parent.Color = RBTreeColor.Red; RotujVLavo(iRBTreeNode.Parent.Parent); } } } _treeNode.Color = RBTreeColor.Black; }
/// <summary> /// Adds the specified key and value to the dictionary. /// </summary> /// <param name="key">The key of the element to add.</param> /// <param name="value">The value of the element to add. The value can be null for reference types.</param> /// <exception cref="System.ArgumentException"> /// An element with the same key already exists. /// </exception> public void Add(TKey key, TValue value) { Contract.Requires(key != null); Contract.Requires(value != null); int ret = 0; RBTreeNode <TKey, TValue> rbTreeNode = new RBTreeNode <TKey, TValue>(); RBTreeNode <TKey, TValue> tmpRBTreeNode = _treeNode; // Vyhladam svojho otca kde sa pojdem vlozit. while (tmpRBTreeNode != _treeNodeNull) { rbTreeNode.Parent = tmpRBTreeNode; ret = key.CompareTo(tmpRBTreeNode.Key); if (ret == 0) { throw (new ArgumentException(string.Format("An element with the same key already exists. Key: {0}", key))); } if (ret > 0) { tmpRBTreeNode = tmpRBTreeNode.RightNode; } else { tmpRBTreeNode = tmpRBTreeNode.LeftNode; } } rbTreeNode.Key = key; rbTreeNode.Value = value; rbTreeNode.LeftNode = _treeNodeNull; // Lavy syn je null rbTreeNode.RightNode = _treeNodeNull; // Pravy syn je null // Ak niesom TopItem tak sa priradim otcovi if (rbTreeNode.Parent != null) { // Priradim sa otcovi bud ako pravy, alebo ako pravy podstrom ret = rbTreeNode.Key.CompareTo(rbTreeNode.Parent.Key); if (ret > 0) { rbTreeNode.Parent.RightNode = rbTreeNode; } else { rbTreeNode.Parent.LeftNode = rbTreeNode; } } else { //inak sa prehlasim za koren _treeNode = rbTreeNode; } //reorganizujem sa Reorganizuj(rbTreeNode); _treeNodeLast = rbTreeNode; _itemsCount++; }