예제 #1
0
/*
 * пригодится, когда дерево оооочень большое будет, так ое, что  список переполнит оперативную память
 *          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);
        }
예제 #2
0
        /// <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);
        }