public static int H(PxEntry tree) { return(tree.Tag() == 0 ? 0 : 1 + Math.Max(H(tree.UElementUnchecked(1).Field(1)), H(tree.UElementUnchecked(1).Field(2)))); }
/* * пригодится, когда дерево оооочень большое будет, так ое, что список переполнит оперативную память * private void ChangeBalanceSlowlyLongSequence(object element, PxEntry lastUnBalanceNode) * { * var nodeBalance = lastUnBalanceNode; * // foreach (bool isLeft in listEntries4Balance) * int com = 0; * while (nodeBalance.Tag() != 0 && (com=elementDepth(element, nodeBalance.UElementUnchecked(1).Field(0))) != 0) * { * var nodeEntry = nodeBalance.UElementUnchecked(1); * var balanceEntry = nodeEntry.Field(3); * if (com < 0) * { * balanceEntry.Set((int) balanceEntry.Get().Value + 1); * nodeBalance = nodeEntry.Field(1); * } * else * { * balanceEntry.Set((int) balanceEntry.Get().Value - 1); * nodeBalance = nodeEntry.Field(2); * } * } * } * */ /// <summary> /// балансирует дерево поворотом влево /// </summary> /// <param name="root">PxEntry балансируемой вершины с балансом=-2</param> /// <param name="entries">balance entries of path from prime node to added(excluded from entries), and them balaces</param> private static void FixWithRotateLeft(PxEntry root, List <KeyValuePair <PxEntry, int> > entries) { var rootEntry = root.UElementUnchecked(1); var r = rootEntry.Field(2); //Right; var rEntry = r.UElementUnchecked(1); var rl = rEntry.Field(1); //right of Left; var rBalance = entries[1].Value; if (rBalance == 1) { var rlEntry = rl.UElementUnchecked(1); rlEntry.Field(3).Set(0); //запоминаем RL var rlold = rl.GetHead(); int rlBalance = (entries.Count == 2 ? 0 : entries[2].Value); //Изменяем правую rl.SetHead(rlEntry.Field(2).GetHead()); entries[1].Key.Set(Math.Min(0, -rlBalance)); //запоминаем правую var oldR = r.GetHead(); //изменяем корневую r.SetHead(rlEntry.Field(1).GetHead()); entries[0].Key.Set(Math.Max(0, -rlBalance)); //запоминаем корневую var rootOld = root.GetHead(); //RL теперь корень root.SetHead(rlold); rootEntry = root.UElementUnchecked(1); //подставляем запомненые корень и правую. rootEntry.Field(1).SetHead(rootOld); rootEntry.Field(2).SetHead(oldR); return; } if (rBalance == -1) { entries[0].Key.Set(0); entries[1].Key.Set(0); } else //0 { entries[0].Key.Set(-1); entries[1].Key.Set(1); } var rOld = r.GetHead(); r.SetHead(rl.GetHead()); rl.SetHead(root.GetHead()); root.SetHead(rOld); }
/// <summary> /// балансирует дерево поворотом вправо /// </summary> /// <param name="root">PxEntry балансируемой вершины с балансом=2</param> /// <param name="entries"> пары: PxEntry содержащая баланс и баланс, соответсвующие пути от балансируемой вершины (включительно) до добавленой не включительно</param> private static void FixWithRotateRight(PxEntry root, List <KeyValuePair <PxEntry, int> > entries) { var rootEntry = root.UElementUnchecked(1); var l = rootEntry.Field(1); //Left; var lEntry = l.UElementUnchecked(1); var lr = lEntry.Field(2); //right of Left; var leftBalance = entries[1].Value; if (leftBalance == -1) { var lrEntry = lr.UElementUnchecked(1); var lrold = lr.GetHead(); int lrBalance = (entries.Count == 2 ? 0 : entries[2].Value); lr.SetHead(lrEntry.Field(1).GetHead()); entries[1].Key.Set(Math.Max(0, -lrBalance)); var oldR = l.GetHead(); l.SetHead(lrEntry.Field(2).GetHead()); entries[0].Key.Set(Math.Min(0, -lrBalance)); var rootOld = root.GetHead(); root.SetHead(lrold); rootEntry = root.UElementUnchecked(1); rootEntry.Field(2).SetHead(rootOld); rootEntry.Field(1).SetHead(oldR); rootEntry.Field(3).Set(0); return; } if (leftBalance == 1) // 1 { entries[0].Key.Set(0); entries[1].Key.Set(0); } else // 0 { entries[0].Key.Set(1); entries[1].Key.Set(-1); } var lOld = l.GetHead(); l.SetHead(lr.GetHead()); lr.SetHead(root.GetHead()); root.SetHead(lOld); }