コード例 #1
0
ファイル: RBNode.cs プロジェクト: beda2280/wpf-1
        // search for x within the index range [low, high)
        protected RBFinger <T> BoundedSearch(T x, int low, int high, Comparison <T> comparison)
        {
            RBFinger <T> result;
            int          compL, compR;
            RBNode <T>   leftChild = LeftChild, rightChild = RightChild;
            int          left = 0, right = Size;

            // determine whether to search the left subtree
            if (high <= LeftSize)
            {   // allowed range is entirely within left subtree
                compL = -1;
            }
            else
            {
                if (low >= LeftSize)
                {   // left subtree does not intersect allowed range
                    leftChild = null;
                    left      = low - LeftSize;
                }
                compL = (left < Size) ? comparison(x, GetItemAt(left)) : +1;
            }

            if (compL <= 0)
            {   // x is in the left subtree, or at the leftmost position in this node
                if (leftChild == null)
                {
                    result = new RBFinger <T>()
                    {
                        Node = this, Offset = left, Index = left, Found = (compL == 0)
                    }
                }
                ;
                else
                {
                    result = leftChild.BoundedSearch(x, low, high, comparison);
                    if (compL == 0 && !result.Found)
                    {
                        result = new RBFinger <T>()
                        {
                            Node = this, Offset = 0, Index = LeftSize, Found = true
                        }
                    }
                    ;
                }
                return(result);
            }

            // determine whether to search the right subtree
            if (LeftSize + Size <= low)
            {   // allowed range is entirely within right subtree
                compR = +1;
            }
            else
            {
                if (LeftSize + Size >= high)
                {   // right subtree does not intersect allowed range
                    rightChild = null;
                    right      = high - LeftSize;
                }
                // by symmetry with the left case, we should write
                // compR = (right > 0) ? comparison(x, GetItemAt(right-1)) : -1;
                // but since we know Size>0 and high>LeftSize, we can abbreviate to
                compR = comparison(x, GetItemAt(right - 1));
            }

            if (compR > 0)
            {   // x is in the right subtree, or after the rightmost position in this node
                if (rightChild == null)
                {
                    result = new RBFinger <T>()
                    {
                        Node = this, Offset = right, Index = LeftSize + right, Found = false
                    }
                }
                ;
                else
                {
                    int delta = LeftSize + Size;
                    result        = rightChild.BoundedSearch(x, low - delta, high - delta, comparison);
                    result.Index += delta;
                }
                return(result);
            }

            // if we get here, x is in this node in the range [left+1, right)
            bool found;
            int  offset = BinarySearch(x, left + 1, right - 1, comparison, compR, out found);

            result = new RBFinger <T>()
            {
                Node = this, Offset = offset, Index = LeftSize + offset, Found = found
            };
            return(result);
        }

        int BinarySearch(T x, int low, int high, Comparison <T> comparison, int compHigh, out bool found)
        {
            while (high - low > BinarySearchThreshold)
            {
                int mid = (high + low) / 2;
                int c   = comparison(x, GetItemAt(mid));
                if (c <= 0)
                {
                    compHigh = c;
                    high     = mid;
                }
                else
                {
                    low = mid + 1;
                }
            }

            int comp = 0;

            for (; low < high; ++low)
            {
                comp = comparison(x, GetItemAt(low));
                if (comp <= 0)
                {
                    break;
                }
            }
            if (low == high)
            {
                comp = compHigh;
            }

            found = (comp == 0);
            return(low);
        }
コード例 #2
0
        // Token: 0x0600768D RID: 30349 RVA: 0x0021DB38 File Offset: 0x0021BD38
        protected RBFinger <T> BoundedSearch(T x, int low, int high, Comparison <T> comparison)
        {
            RBNode <T> rbnode  = this.LeftChild;
            RBNode <T> rbnode2 = this.RightChild;
            int        num     = 0;
            int        num2    = this.Size;
            int        num3;

            if (high <= this.LeftSize)
            {
                num3 = -1;
            }
            else
            {
                if (low >= this.LeftSize)
                {
                    rbnode = null;
                    num    = low - this.LeftSize;
                }
                num3 = ((num < this.Size) ? comparison(x, this.GetItemAt(num)) : 1);
            }
            RBFinger <T> result;

            if (num3 <= 0)
            {
                if (rbnode == null)
                {
                    result = new RBFinger <T>
                    {
                        Node   = this,
                        Offset = num,
                        Index  = num,
                        Found  = (num3 == 0)
                    };
                }
                else
                {
                    result = rbnode.BoundedSearch(x, low, high, comparison);
                    if (num3 == 0 && !result.Found)
                    {
                        result = new RBFinger <T>
                        {
                            Node   = this,
                            Offset = 0,
                            Index  = this.LeftSize,
                            Found  = true
                        };
                    }
                }
                return(result);
            }
            int num4;

            if (this.LeftSize + this.Size <= low)
            {
                num4 = 1;
            }
            else
            {
                if (this.LeftSize + this.Size >= high)
                {
                    rbnode2 = null;
                    num2    = high - this.LeftSize;
                }
                num4 = comparison(x, this.GetItemAt(num2 - 1));
            }
            if (num4 > 0)
            {
                if (rbnode2 == null)
                {
                    result = new RBFinger <T>
                    {
                        Node   = this,
                        Offset = num2,
                        Index  = this.LeftSize + num2,
                        Found  = false
                    };
                }
                else
                {
                    int num5 = this.LeftSize + this.Size;
                    result        = rbnode2.BoundedSearch(x, low - num5, high - num5, comparison);
                    result.Index += num5;
                }
                return(result);
            }
            bool found;
            int  num6 = this.BinarySearch(x, num + 1, num2 - 1, comparison, num4, out found);

            result = new RBFinger <T>
            {
                Node   = this,
                Offset = num6,
                Index  = this.LeftSize + num6,
                Found  = found
            };
            return(result);
        }