Esempio n. 1
0
        private bool TryGetRecord(int code, out record rec)
        {
            if (codeRec.TryGetValue(code, out rec))
            {
                return(true);
            }
            if (tofilldictionary)
            {
                return(false);
            }
            PxEntry entry = tree_fix.Root.BinarySearchFirst(en => ((int)en.Field(0).Get()).CompareTo(code));

            if (entry.IsEmpty)
            {
                return(false);
            }
            rec = AddRecordToDictionary((object[])entry.Get());
            return(true);
        }
        //private static object[] ToTreeObjectWithBalance(ToTreeObjectParams @params, ref int h)
        //{
        //    if (@params.Len == 0) return Empty;
        //    h++;
        //    if (@params.Len == 1)
        //        return new object[]
        //        {
        //            1, new[]
        //            {
        //                // запись
        //                @params.Elements[@params.Beg], // значение
        //                Empty,
        //                Empty,
        //                0
        //            }
        //        };
        //    int leftH = 0, rightH = 0, l = @params.Len;
        //    @params.Len /= 2;
        //    var left = ToTreeObjectWithBalance(@params, ref leftH);
        //    @params.Beg += @params.Len + 1;
        //    @params.Len = l - @params.Len - 1;
        //    return new object[]
        //    {
        //        1, new[]
        //        {
        //            // запись
        //            @params.Elements[@params.Beg + @params.Len], // значение
        //            left,
        //            ToTreeObjectWithBalance(@params, ref rightH),
        //            leftH - rightH
        //        }
        //    };
        //}

        public PxEntry BinarySearch(int key)
        {
            var entry = Root;

            while (true)
            {
                //if (entry.Tag() == 0) return new PxEntry(entry.Typ, Int64.MinValue, entry.fis);
                PxEntry elementEntry = entry.Field(0);
                // Можно сэкономить на запоминании входа для uelement'а
                var o = (int)elementEntry.Get();
                if (o == key)
                {
                    return(elementEntry);
                }
                if (o == Int32.MinValue)
                {
                    return(new PxEntry(entry.Typ, Int64.MinValue, entry.fis));
                }
                entry = entry.Field(1).UElementUnchecked(1).Field(o < key ? 0 : 1);
            }
        }
Esempio n. 3
0
        public PxEntry BinarySearch(Tkey key)
        {
            var entry = Root;

            while (true)
            {
                //if (entry.Tag() == 0) return new PxEntry(entry.Typ, Int64.MinValue, entry.fis);
                PxEntry elementEntry = entry.Field(0);

                // Можно сэкономить на запоминании входа для uelement'а
                var o = getKey(elementEntry.Get());
                if (Equals(o, key))
                {
                    return(elementEntry);
                }
                if (Equals(o, keyOfEmpty))
                {
                    return(new PxEntry(entry.Typ, Int64.MinValue, entry.fis));
                }
                entry = entry.Field(1).UElementUnchecked(1).Field(keyComparer(o, key) < 0 ? 0 : 1);
            }
        }
Esempio n. 4
0
        /// <summary>
        /// Поместить элемент в дерево в соответствии со значением функции сравнения,
        ///  вернуть ссылку на голову нового дерева
        /// </summary>
        /// <param name="element"></param>
        /// <returns>была ли изменена высота дерева</returns>
        public void Add(object element)
        {
            var node = Root;
            var lastUnBalanceNode = node;

            listEntries4Balance.Clear();
            //int h = 0;
            Tkey   key, keyAdd = getKey(element);
            object value;

            while (Equals(key = getKey((value = node.Field(0).Get())), keyOfEmpty))
            {
                //  h++;
                counter++;
                PxEntry balanceEntry = node.Field(3);
                var     balance      = (int)balanceEntry.Get();
                int     cmp          = keyComparer(key, keyAdd);
                if (cmp == 0)
                {
                    var left  = node.Field(1).GetHead();
                    var right = node.Field(2).GetHead();
                    node.Set(new []
                    {
                        element,
                        Empty,
                        Empty,
                        balance
                    });
                    node.Field(1).SetHead(left);
                    node.Field(2).SetHead(right);
                    return;
                }
                if (balance != 0)
                {
                    lastUnBalanceNode = node;
                    listEntries4Balance.Clear();
                }
                var goLeft = cmp < 0;
                //TODO catch overflow memory
                listEntries4Balance.Add(new KeyValuePair <PxEntry, int>(balanceEntry, goLeft ? balance + 1 : balance - 1));
                node = node.Field(goLeft ? 1 : 2);
            }
            // когда дерево пустое, организовать одиночное значение
            node.Set(new[]
            {
                element, new object[] { 0, null }, new object[] { 0, null }, 0
            });
            if (listEntries4Balance.Count == 0)
            {
                return;
            }
            for (int i = 0; i < listEntries4Balance.Count; i++)
            {
                listEntries4Balance[i].Key.Set(listEntries4Balance[i].Value);
            }
            //  ChangeBalanceSlowlyLongSequence(element, lastUnBalanceNode);
            int b = listEntries4Balance[0].Value;

            if (b == 2)
            {
                FixWithRotateRight(lastUnBalanceNode, listEntries4Balance);
            }
            else if (b == -2)
            {
                FixWithRotateLeft(lastUnBalanceNode, listEntries4Balance);
            }
            //  return true;
        }
Esempio n. 5
0
        /// <summary>
        /// Поместить элемент в дерево в соответствии со значением функции сравнения,
        ///  вернуть ссылку на голову нового дерева
        /// </summary>
        /// <param name="element"></param>
        /// <returns>была ли изменена высота дерева</returns>
        public void Add(object element)
        {
            var node = Root;
            var lastUnBalanceNode = node;

            listEntries4Balance.Clear();
            int h = 0;

            while (node.Tag() != 0)
            {
                h++;
                var nodeEntry = node.UElementUnchecked(1);
                counter++;
                int     cmp          = elementDepth(element, nodeEntry.Field(0));
                PxEntry balanceEntry = nodeEntry.Field(3);
                var     balance      = (int)balanceEntry.Get();
                if (cmp == 0)
                {
                    var left  = nodeEntry.Field(1).GetHead();
                    var right = nodeEntry.Field(2).GetHead();
                    node.Set(new object[]
                    {
                        1, new[]
                        {
                            element,
                            Empty,
                            Empty,
                            balance
                        }
                    });
                    node.UElementUnchecked(1).Field(1).SetHead(left);
                    node.UElementUnchecked(1).Field(2).SetHead(right);
                    return;
                }
                if (balance != 0)
                {
                    lastUnBalanceNode = node;
                    listEntries4Balance.Clear();
                }
                var goLeft = cmp < 0;
                //TODO catch overflow memory
                listEntries4Balance.Add(new KeyValuePair <PxEntry, int>(balanceEntry,
                                                                        goLeft ? balance + 1 : balance - 1));
                node = nodeEntry.Field(goLeft ? 1 : 2);
            }
            // когда дерево пустое, организовать одиночное значение
            node.Set(new object[]
            {
                1, new[]
                {
                    element, new object[] { 0, null }, new object[] { 0, null }, 0
                }
            });
            if (listEntries4Balance.Count == 0)
            {
                return;
            }
            for (int i = 0; i < listEntries4Balance.Count; i++)
            {
                listEntries4Balance[i].Key.Set(listEntries4Balance[i].Value);
            }
            //  ChangeBalanceSlowlyLongSequence(element, lastUnBalanceNode);
            int b = listEntries4Balance[0].Value;

            if (b == 2)
            {
                FixWithRotateRight(lastUnBalanceNode, listEntries4Balance);
            }
            else if (b == -2)
            {
                FixWithRotateLeft(lastUnBalanceNode, listEntries4Balance);
            }
            //  return true;
        }