Exemple #1
0
        /// <summary>Returns all sub-trees enumerated from left to right.</summary>
        /// <returns>Enumerated sub-trees or empty if tree is empty.</returns>
        public IEnumerable <ImMap <V> > Enumerate()
        {
            if (IsEmpty)
            {
                yield break;
            }

            var parents = new ImMap <V> [this.GetHeight()];

            var node        = this;
            var parentCount = -1;

            while (!node.IsEmpty || parentCount != -1)
            {
                if (!node.IsEmpty)
                {
                    parents[++parentCount] = node;
                    node = node.GetLeft();
                }
                else
                {
                    node = parents[parentCount--];
                    yield return(node);

                    node = node.GetRight();
                }
            }
        }
Exemple #2
0
            internal Branch(int key, V value, ImMap <V> left, int rightHeight, ImMap <V> right) : base(key, value)
            {
                Left  = left;
                Right = right;
                var leftHeight = left is Branch b ? b.Height : 1;

                Height = leftHeight > rightHeight ? leftHeight + 1 : rightHeight + 1;
            }
Exemple #3
0
 private static ImMap <V> BranchOrLeaf(int key, V value, ImMap <V> left, ImMap <V> right)
 {
     if (left == Empty && right == Empty)
     {
         return(new ImMap <V>(key, value));
     }
     return(new Branch(key, value, left, right));
 }
Exemple #4
0
        ///
        public ImMap <V> AddOrUpdate(int key, V value)
        {
            var mapKey = Key;

            var b = this as Branch;

            if (b == null) // means the leaf node
            {
                // update the leaf
                if (mapKey == key)
                {
                    return(new ImMap <V>(key, value));
                }

                return(key < mapKey // search for node
                    ? new Branch(mapKey, Value, new ImMap <V>(key, value), Empty, 2)
                    : new Branch(mapKey, Value, Empty, new ImMap <V>(key, value), 2));
            }

            // the empty branch node
            var height = b.Height;

            if (height == 0)
            {
                return(new ImMap <V>(key, value));
            }

            // update the branch key and value
            var left  = b.Left;
            var right = b.Right;

            if (mapKey == key)
            {
                return(new Branch(key, value, left, right, height));
            }

            if (key < mapKey)
            {
                left = left.AddOrUpdate(key, value);
            }
            else
            {
                right = right.AddOrUpdate(key, value);
            }

            // Now balance!!!
            return(ImMap.Balance(mapKey, Value, left, right));
        }
Exemple #5
0
        private static ImMap <V> Balance(int key, V value, ImMap <V> left, ImMap <V> right)
        {
            var delta = left.GetHeight() - right.GetHeight();

            if (delta >= 2) // left is longer by 2, rotate left
            {
                var leftLeft  = left.GetLeft();
                var leftRight = left.GetRight();
                if (leftRight.GetHeight() - leftLeft.GetHeight() == 1)
                {
                    // double rotation:
                    //      5     =>     5     =>     4
                    //   2     6      4     6      2     5
                    // 1   4        2   3        1   3     6
                    //    3        1
                    return(new Branch(leftRight.Key, leftRight.Value,
                                      BranchOrLeaf(left.Key, left.Value, leftLeft, leftRight.GetLeft()),
                                      BranchOrLeaf(key, value, leftRight.GetRight(), right)));
                }

                // todo: do we need this?
                // one rotation:
                //      5     =>     2
                //   2     6      1     5
                // 1   4              4   6
                return(new Branch(left.Key, left.Value, leftLeft, BranchOrLeaf(key, value, leftRight, right)));
            }

            if (delta <= -2)
            {
                var rightLeft  = right.GetLeft();
                var rightRight = right.GetRight();
                if (rightLeft.GetHeight() - rightRight.GetHeight() == 1)
                {
                    return(new Branch(rightLeft.Key, rightLeft.Value,
                                      BranchOrLeaf(key, value, left, rightLeft.GetLeft()),
                                      BranchOrLeaf(right.Key, right.Value, rightLeft.GetRight(), rightRight)));
                }

                return(new Branch(right.Key, right.Value, BranchOrLeaf(key, value, left, rightLeft), rightRight));
            }

            return(new Branch(key, value, left, right));
        }
Exemple #6
0
 internal Branch(int key, V value, ImMap <V> left, ImMap <V> right, int height) : base(key, value)
 {
     Left   = left;
     Right  = right;
     Height = height;
 }
Exemple #7
0
 internal Branch(int key, V value, int leftHeight, ImMap <V> left, int rightHeight, ImMap <V> right) : base(key, value)
 {
     Left   = left;
     Right  = right;
     Height = leftHeight > rightHeight ? leftHeight + 1 : rightHeight + 1;
 }