Ejemplo n.º 1
0
        // returns -# for failure, or number of blacks to leaves
        public virtual int TestIntegrityNode(RedBlackNode <KeyType, DataType> node)
        {
            if (node == null)
            {
                return(1);
            }

            if (node.Left != null)
            {
                if (node.Left.Parent != node)
                {
                    return(-1);
                }
                if (node.Left.Key.CompareTo(node.Key) > 0)
                {
                    return(-3);
                }
            }
            if (node.Right != null)
            {
                if (node.Right.Parent != node)
                {
                    return(-2);
                }
                if (node.Right.Key.CompareTo(node.Key) < 0)
                {
                    return(-4);
                }
            }
            if (node.Color == RED && ((node.Left != null && node.Left.Color == RED) || (node.Right != null && node.Right.Color == RED)))
            {
                return(-5);
            }

            // Recurse!  Count the number of blacks below us
            int leftCount  = TestIntegrityNode(node.Left);
            int rightCount = TestIntegrityNode(node.Right);

            if (leftCount != rightCount)
            {
                return(-6);
            }

            return(leftCount + (node.Color == BLACK ? 1 : 0));
        }
Ejemplo n.º 2
0
        /***** Remove Operation *****/

        ///<summary>
        /// Remove
        /// removes the key and data object (delete)
        ///<summary>
        public virtual bool Remove(KeyType key)
        {
            if (key == null)
            {
                throw(new ArgumentNullException());
            }

            // find node
            RedBlackNode <KeyType, DataType> node = Search(key);

            if (node == null)
            {
                return(false);   // not found!
            }
            Delete(node);

            return(true);
        }
Ejemplo n.º 3
0
        // We may have multiple, so check against object
        public virtual bool Remove(KeyType key, DataType obj)
        {
            if (obj == null)
            {
                throw (new RedBlackException("RedBlackNode object is null"));
            }

            // find node
            RedBlackNode <KeyType, DataType> node = Search(key, obj);

            if (node == null)
            {
                // not found!
                return(false);
            }

            Delete(node);
            return(true);
        }
        // don't call remove-- derived classes will remove!
        public virtual void ChangeSalience(DataType obj, double before, double after)
        {
            if (obj == null)
            {
                throw (new RedBlackException("ChangeSalience object is null"));
            }

            // find node
            RedBlackNode <double, DataType> node = Search(before, obj);

            if (node == null)
            {
                throw (new RedBlackException("ChangeSalience object not found"));
            }

            Delete(node);

            Add(after, obj);
        }
Ejemplo n.º 5
0
        ///<summary>
        /// GetMaxKey
        /// Returns the maximum key value
        ///<summary>
        public KeyType GetMaxKey()
        {
            RedBlackNode <KeyType, DataType> treeNode = rbTree;

            if (treeNode == null)
            {
                throw (new RedBlackException("RedBlack tree is empty"));
            }

            // traverse to the extreme right to find the largest key
            while (treeNode.Right != null)
            {
                treeNode = treeNode.Right;
            }

            lastNodeFound = treeNode;

            return(treeNode.Key);
        }
Ejemplo n.º 6
0
        ///<summary>
        /// RotateRight
        /// Rebalance the tree by rotating the nodes to the right
        ///</summary>
        public void RotateRight(RedBlackNode <KeyType, DataType> x)
        {
            // pushing node x down and to the Right to balance the tree. x's Left child (y)
            // replaces x (since x < y), and y's Right child becomes x's Left child
            // (since it's < x but > y).

            RedBlackNode <KeyType, DataType> y = x.Left;                 // get x's Left node, this becomes y

            // set x's Right link
            x.Left = y.Right;                                                   // y's Right child becomes x's Left child

            // modify parents
            if (y.Right != null)
            {
                y.Right.Parent = x;                                             // sets y's Right Parent to x
            }
            if (y != null)
            {
                y.Parent = x.Parent; // set y's Parent to x's Parent
            }
            if (x.Parent != null)    // null=rbTree, could also have used rbTree
            {                        // determine which side of it's Parent x was on
                if (x == x.Parent.Right)
                {
                    x.Parent.Right = y;                                         // set Right Parent to y
                }
                else
                {
                    x.Parent.Left = y;                                          // set Left Parent to y
                }
            }
            else
            {
                rbTree = y;                                                             // at rbTree, set it to y
            }
            // link x and y
            y.Right = x;                                        // put x on y's Right
            if (x != null)                                      // set y as x's Parent
            {
                x.Parent = y;
            }
        }
 public override void Deserialize(SerializationReader reader)
 {
     salienceSum = reader.ReadDouble();  // salienceSum = info.GetDouble("salienceSum");
     // : base(info, ctxt)
     intCount = reader.ReadInt32();
     if (intCount != 0)
     {
         RedBlackNode <double, DataType>[] containers = new RedBlackNode <double, DataType> [intCount];
         int ii = 0;
         rbTree = DeserializeTree(reader, containers, ref ii);
         for (int jj = 0; jj < intCount; jj++)
         {
             containers[jj].Data = (DataType)reader.ReadPointer();
         }
     }
     else
     {
         rbTree = null;
     }
 }
Ejemplo n.º 8
0
        public RedBlackNode <KeyType, DataType> ContainsUnderNode(DataType obj, RedBlackNode <KeyType, DataType> node)
        {
            if (node == null)
            {
                return(null);
            }

            if (ReferenceEquals(node.Data, obj))
            {
                return(node);
            }

            RedBlackNode <KeyType, DataType> below = ContainsUnderNode(obj, node.Left);

            if (below != null)
            {
                return(below);
            }

            return(ContainsUnderNode(obj, node.Right));
        }
        public DataType SelectSmartItem()
        {
            double position;
            RedBlackNode <double, DataType> result = SelectWeightedItem(smartWeight, out position);

            // Adjust the weight!
            // We expect an object at position to give the following
            double expected = position * 2 * (salienceSum / intCount);

            if (expected > result.Key)
            {
                // Smaller than we expected-- decrease weight!
                smartWeight = (smartWeight + .25) / 2;
            }
            else
            {
                // More even than we expected-- increase weight!
                smartWeight = (smartWeight + 0.5) / 2;
            }

            return(result.Data);
        }
        public DataType SelectRandomItem(RandomSearchQuality quality)
        {
            if (quality == RandomSearchQuality.Fast)
            {
                double position;
                return(SelectWeightedItem(.5, out position).Data);
            }
            else
            {
                int chosen = randgen.Next(Count);
                RedBlackEnumerator <double, DataType> enumerator = GetNodeEnumerator();
                while (enumerator.HasMoreElements())
                {
                    RedBlackNode <double, DataType> node = enumerator.NextElement();
                    if (chosen-- == 0)
                    {
                        return(node.Data);
                    }
                }

                return(default(DataType));
            }
        }
        // Select a codelet by carefully respecting salience
        public DataType SelectExactItem()
        {
            double salienceToGet = randgen.NextDouble() * salienceSum;
            double salienceSoFar = 0;

            RedBlackEnumerator <double, DataType> enumerator = GetNodeEnumerator();

            while (enumerator.HasMoreElements())
            {
                RedBlackNode <double, DataType> node = enumerator.NextElement();
                salienceSoFar += node.Key;
                if (salienceSoFar >= salienceToGet)
                {
                    return(node.Data);
                }
            }

            // Salience calculation failure!
            Console.WriteLine("WARNING: Salience miscalculation!  Max is " + salienceSoFar.ToString() + " not " + salienceSum.ToString());
            salienceSum = salienceSoFar;
            // Try again!
            return(SelectExactItem());
        }
Ejemplo n.º 12
0
 // Initialize a sentinel node (use BLACK as color)
 public RedBlackNode(int color)
 {
     rbnLeft  = rbnRight = rbnParent = null;
     intColor = color;
 }
Ejemplo n.º 13
0
 public void Reset()
 {
     Color   = 0; // red
     rbnLeft = rbnRight = rbnParent = null;
     // don't reset key and data-- new allocater should!
 }
Ejemplo n.º 14
0
        public RedBlackNode <KeyType, DataType> SearchRecursive(KeyType key, DataType obj, RedBlackNode <KeyType, DataType> node)
        {
            if (ReferenceEquals(node.Data, obj))
            {
                return(node);
            }
            if (node == null)
            {
                return(null);
            }

            // One side or the other (or both) ought to be the same key
            RedBlackNode <KeyType, DataType> found = null;

            if (node.Left != null)
            {
                if (key.CompareTo(node.Left.Key) == 0)
                {
                    found = SearchRecursive(key, obj, node.Left);
                }
                else
                {
                    // scale down the right side-- there might be more!
                    RedBlackNode <KeyType, DataType> below = node.Left;
                    while (below != null && key.CompareTo(below.Key) != 0)
                    {
                        below = below.Right;
                    }
                    if (below != null)
                    {
                        found = SearchRecursive(key, obj, below);
                    }
                }
            }
            if (found == null && node.Right != null)
            {
                int rightResult = key.CompareTo(node.Right.Key);
                if (rightResult == 0)
                {
                    found = SearchRecursive(key, obj, node.Right);
                }
                else
                {
                    // scale down the left side-- there might be more!
                    RedBlackNode <KeyType, DataType> below = node.Right;
                    while (below != null && key.CompareTo(below.Key) != 0)
                    {
                        below = below.Left;
                    }
                    if (below != null)
                    {
                        found = SearchRecursive(key, obj, below);
                    }
                }
            }

            return(found);
        }
 public void SerializeTree(SerializationWriter writer, DataType[] elements, ref int ii, RedBlackNode <double, DataType> node)
 {
     if (node == null)
     {
         writer.Write(0.0);
     }
     else
     {
         writer.Write(node.Key);
         writer.Write(node.Color == RED);
         elements[ii++] = node.Data;
         SerializeTree(writer, elements, ref ii, node.Left);
         SerializeTree(writer, elements, ref ii, node.Right);
     }
 }
Ejemplo n.º 16
0
 ///<summary>
 /// Clear
 /// Empties or clears the tree
 ///<summary>
 public virtual void Clear()
 {
     rbTree   = null;
     intCount = 0;
 }
Ejemplo n.º 17
0
        ///<summary>
        /// RestoreAfterDelete
        /// Deletions from red-black trees may destroy the red-black
        /// properties. Examine the tree and restore. Rotations are normally
        /// required to restore it
        ///</summary>
        private void RestoreAfterDelete(RedBlackNode <KeyType, DataType> x, RedBlackNode <KeyType, DataType> x_parent)
        {
            // maintain Red-Black tree balance after deleting node

            RedBlackNode <KeyType, DataType> y;

            while (x != rbTree && (x == null || x.Color == BLACK))
            {
                if (x == x_parent.Left) // determine sub tree from parent
                {
                    y = x_parent.Right; // y is x's sibling
                    if (y.Color == RED)
                    {                   // x is black, y is red - make both black and rotate
                        y.Color        = BLACK;
                        x_parent.Color = RED;
                        RotateLeft(x_parent);
                        y = x_parent.Right;
                    }
                    if ((y.Left == null || y.Left.Color == BLACK) &&
                        (y.Right == null || y.Right.Color == BLACK))
                    {                       // children are both black
                        y.Color = RED;      // change parent to red
                        x       = x_parent; // move up the tree
                        if (x != null)
                        {
                            x_parent = x.Parent;
                        }
                        else
                        {
                            x_parent = null;
                        }
                    }
                    else
                    {
                        if (y.Right == null || y.Right.Color == BLACK)
                        {
                            if (y.Left != null)
                            {
                                y.Left.Color = BLACK;
                            }
                            y.Color = RED;
                            RotateRight(y);
                            y = x_parent.Right;
                        }
                        y.Color        = x_parent.Color;
                        x_parent.Color = BLACK;
                        if (y.Right != null)
                        {
                            y.Right.Color = BLACK;
                        }
                        RotateLeft(x_parent);
                        x        = rbTree;
                        x_parent = null;
                    }
                }
                else
                {       // right subtree - same as code above with right and left swapped
                    y = x_parent.Left;
                    if (y.Color == RED)
                    {
                        y.Color        = BLACK;
                        x_parent.Color = RED;
                        RotateRight(x_parent);
                        y = x_parent.Left;
                    }
                    if ((y.Left == null || y.Left.Color == BLACK) &&
                        (y.Right == null || y.Right.Color == BLACK))
                    {
                        y.Color = RED;
                        x       = x_parent;
                        if (x != null)
                        {
                            x_parent = x.Parent;
                        }
                        else
                        {
                            x_parent = null;
                        }
                    }
                    else
                    {
                        if (y.Left == null || y.Left.Color == BLACK)
                        {
                            if (y.Right != null)
                            {
                                y.Right.Color = BLACK;
                            }
                            y.Color = RED;
                            RotateLeft(y);
                            y = x_parent.Left;
                        }
                        y.Color        = x_parent.Color;
                        x_parent.Color = BLACK;
                        if (y.Left != null)
                        {
                            y.Left.Color = BLACK;
                        }
                        RotateRight(x_parent);
                        x        = rbTree;
                        x_parent = null;
                    }
                }
            }
            if (x != null)
            {
                x.Color = BLACK;
            }
        }
Ejemplo n.º 18
0
        /***** Add Operation *****/

        ///<summary>
        /// Add
        /// args: ByVal key As IComparable, ByVal data As Object
        /// key is object that implements IComparable interface
        /// performance tip: change to use use int type (such as the hashcode)
        ///</summary>
        public virtual void Add(KeyType key, DataType data)
        {
            try
            {
                if (key == null || data == null)
                {
                    throw (new RedBlackException("RedBlackNode key and data must not be null"));
                }

                // traverse tree - find where node belongs
                int result = 0;
                // create new node
                RedBlackNode <KeyType, DataType> node = new RedBlackNode <KeyType, DataType>();
                RedBlackNode <KeyType, DataType> temp = rbTree;                          // grab the rbTree node of the tree

                while (temp != null)
                {       // find Parent
                    node.Parent = temp;
                    result      = key.CompareTo(temp.Key);
                    if (result == 0)
                    {
                        if (temp.Left == null || temp.Right == null)
                        {
                            break; // good enough!
                        }
                    }
                    if (result > 0)
                    {
                        temp = temp.Right;
                    }
                    else
                    {
                        temp = temp.Left;
                    }
                }

                // setup node
                node.Key   = key;
                node.Data  = data;
                node.Left  = null;
                node.Right = null;

                // insert node into tree starting at parent's location
                if (node.Parent != null)
                {
                    result = node.Key.CompareTo(node.Parent.Key);
                    if (result == 0)
                    {
                        if (node.Parent.Right == null)
                        {
                            node.Parent.Right = node;
                        }
                        else
                        {
                            node.Parent.Left = node;
                        }
                    }
                    else
                    {
                        if (result > 0)
                        {
                            node.Parent.Right = node;
                        }
                        else
                        {
                            node.Parent.Left = node;
                        }
                    }
                }
                else
                {
                    rbTree = node;                  // first node added
                }
                RestoreAfterInsert(node);           // restore red-black properities

                lastNodeFound = node;

                intCount = intCount + 1;
            }
            catch (Exception e)
            {
                Console.WriteLine("RedBlackTree::Add threw " + e.Message);
            }
        }
Ejemplo n.º 19
0
 public RedBlackTree()
 {
     rbTree        = null;
     lastNodeFound = null;
 }
        public RedBlackNode <double, DataType> SelectWeightedItem(double weight, out double position)
        {
            if (IsEmpty())
            {
                position = .5;
                return(null);
            }

            double selector = randgen.NextDouble();

            // Otherwise, we have a proper tree!
            double left  = 0;                              // left possible-position
            double right = 1;                              // right possible-position
            RedBlackNode <double, DataType> node = rbTree; // current node
            double expectBelow = salienceSum;              // total salience below node

            // Scale down tree
            while (node.Left != null && node.Right != null)
            {
                // should we take this node?
                double fraction = node.Key / expectBelow;
                if (selector < fraction)
                {
                    position = (left + right) / 2;
                    return(node);
                }
                // do we recurse on left?
                if (selector < fraction + weight)
                {
                    node         = node.Left;          // update node
                    selector    -= fraction;           // adjust selector from 0 to 1
                    selector    /= weight;
                    right        = (left + right) / 2; // adjust possible range
                    expectBelow *= weight;             // change expected below
                }
                else
                {
                    node         = node.Right;          // update node
                    selector    -= fraction + weight;   // adjust salience from 0 to 1
                    selector    /= 1 - (fraction + weight);
                    left         = (left + right) / 2;  // adjust possible range
                    expectBelow *= (1 - weight);        // change expected below
                    fraction     = (weight + .5) / 2;   // diff between left and write is less
                }
            }

            if (node.Left == null && node.Right == null)
            {
                // this is a leaf-- take it!
                position = (left + right) / 2;
                return(node);
            }
            else
            {
                // choose between these two nodes
                RedBlackNode <double, DataType> other = (node.Left == null ? node.Right : node.Left);
                double nodesSum = node.Key + other.Key;
                if (selector * nodesSum < node.Key)
                {
                    position = (2 * left + right) / 3;
                    return(node);
                }
                else
                {
                    position = (left + 2 * right) / 3;
                    return(other);
                }
            }
        }
Ejemplo n.º 21
0
        ///<summary>
        /// NextNode
        ///</summary>
        public RedBlackNode <KeyType, DataType> NextElement()
        {
            if (stack.Count == 0)
            {
                throw(new RedBlackException("Element not found"));
            }

            // the top of stack will always have the next item
            // get top of stack but don't remove it as the next nodes in sequence
            // may be pushed onto the top
            // the stack will be popped after all the nodes have been returned
            RedBlackNode <KeyType, DataType> node = stack.Peek();        //next node in sequence

            if (ascending)
            {
                if (node.Right == null)
                {
                    // yes, top node is lowest node in subtree - pop node off stack
                    RedBlackNode <KeyType, DataType> tn = stack.Pop();
                    // peek at right node's parent
                    // get rid of it if it has already been used
                    while (HasMoreElements() && stack.Peek().Right == tn)
                    {
                        tn = stack.Pop();
                    }
                }
                else
                {
                    // find the next items in the sequence
                    // traverse to left; find lowest and push onto stack
                    RedBlackNode <KeyType, DataType> tn = node.Right;
                    while (tn != null)
                    {
                        stack.Push(tn);
                        tn = tn.Left;
                    }
                }
            }
            else            // descending, same comments as above apply
            {
                if (node.Left == null)
                {
                    // walk the tree
                    RedBlackNode <KeyType, DataType> tn = stack.Pop();
                    while (HasMoreElements() && stack.Peek().Left == tn)
                    {
                        tn = stack.Pop();
                    }
                }
                else
                {
                    // determine next node in sequence
                    // traverse to left subtree and find greatest node - push onto stack
                    RedBlackNode <KeyType, DataType> tn = node.Left;
                    while (tn != null)
                    {
                        stack.Push(tn);
                        tn = tn.Right;
                    }
                }
            }

            // the following is for .NET compatibility (see MoveNext())
            Key   = node.Key;
            Value = node.Data;

            return(node);
        }
Ejemplo n.º 22
0
 public virtual void Deserialize(SerializationReader reader)
 {
     intCount      = reader.ReadInt32();                                     // intCount = info.GetInt32("intCount");
     rbTree        = (RedBlackNode <KeyType, DataType>)reader.ReadPointer(); // rbTree = (RedBlackNode<KeyType, DataType>)info.GetValue("rbTree", typeof(RedBlackNode<KeyType, DataType>));
     lastNodeFound = null;
 }
Ejemplo n.º 23
0
        ///<summary>
        /// RestoreAfterInsert
        /// Additions to red-black trees usually destroy the red-black
        /// properties. Examine the tree and restore. Rotations are normally
        /// required to restore it
        ///</summary>
        private void RestoreAfterInsert(RedBlackNode <KeyType, DataType> x)
        {
            // x and y are used as variable names for brevity, in a more formal
            // implementation, you should probably change the names

            RedBlackNode <KeyType, DataType> y;

            // maintain red-black tree properties after adding x
            while (x != rbTree && x.Parent.Color == RED)
            {
                // Parent node is .Colored red;
                if (x.Parent == x.Parent.Parent.Left) // determine traversal path
                {                                     // is it on the Left or Right subtree?
                    y = x.Parent.Parent.Right;        // get uncle
                    if (y != null && y.Color == RED)
                    {                                 // uncle is red; change x's Parent and uncle to black
                        x.Parent.Color = BLACK;
                        y.Color        = BLACK;
                        // grandparent must be red. Why? Every red node that is not
                        // a leaf has only black children
                        x.Parent.Parent.Color = RED;
                        x = x.Parent.Parent;                                                                            // continue loop with grandparent
                    }
                    else
                    {
                        // uncle is black; determine if x is greater than Parent
                        if (x == x.Parent.Right)
                        {                               // yes, x is greater than Parent; rotate Left
                                                        // make x a Left child
                            x = x.Parent;
                            RotateLeft(x);
                        }
                        // no, x is less than Parent
                        x.Parent.Color        = BLACK;                                  // make Parent black
                        x.Parent.Parent.Color = RED;                                    // make grandparent black
                        RotateRight(x.Parent.Parent);                                   // rotate right
                    }
                }
                else
                {                       // x's Parent is on the Right subtree
                                        // this code is the same as above with "Left" and "Right" swapped
                    y = x.Parent.Parent.Left;
                    if (y != null && y.Color == RED)
                    {
                        x.Parent.Color        = BLACK;
                        y.Color               = BLACK;
                        x.Parent.Parent.Color = RED;
                        x = x.Parent.Parent;
                    }
                    else
                    {
                        if (x == x.Parent.Left)
                        {
                            x = x.Parent;
                            RotateRight(x);
                        }
                        x.Parent.Color        = BLACK;
                        x.Parent.Parent.Color = RED;
                        RotateLeft(x.Parent.Parent);
                    }
                }
            }
            if (rbTree != null)
            {
                rbTree.Color = BLACK;                   // rbTree should always be black
            }
        }
Ejemplo n.º 24
0
 public DataOnly(RedBlackNode <KeyType, DataType> tnode, bool ascending)
 {
     enumerator = new RedBlackEnumerator <KeyType, DataType>(tnode, ascending);
 }
Ejemplo n.º 25
0
        ///<summary>
        /// Delete
        /// Delete a node from the tree and restore red black properties
        ///<summary>
        public void Delete(RedBlackNode <KeyType, DataType> z)
        {
            try
            {
                // A node to be deleted will be:
                //		1. a leaf with no children
                //		2. have one child
                //		3. have two children
                // If the deleted node is red, the red black properties still hold.
                // If the deleted node is black, the tree needs rebalancing

                RedBlackNode <KeyType, DataType> x; // work node to contain the replacement node
                RedBlackNode <KeyType, DataType> y; // work node

                // find the replacement node (the successor to x) - the node one with
                // at *most* one child.
                if (z.Left == null || z.Right == null)
                {
                    y = z;                                              // node has sentinel as a child
                }
                else
                {
                    // z has two children, find replacement node which will
                    // be the leftmost node greater than z
                    y = z.Right;                        // traverse right subtree
                    while (y.Left != null)              // to find next node in sequence
                    {
                        y = y.Left;
                    }
                }

                // at this point, y contains the replacement node. it's content will be copied
                // to the valules in the node to be deleted

                // x (y's only child) is the node that will be linked to y's old parent.
                if (y.Left != null)
                {
                    x = y.Left;
                }
                else
                {
                    x = y.Right;
                }

                // replace x's parent with y's parent and
                // link x to proper subtree in parent
                // this removes y from the chain
                if (x != null)
                {
                    x.Parent = y.Parent;
                }
                if (y.Parent != null)
                {
                    if (y == y.Parent.Left)
                    {
                        y.Parent.Left = x;
                    }
                    else
                    {
                        y.Parent.Right = x;
                    }
                }
                else
                {
                    rbTree = x;                 // make x the root node
                }
                // copy the values from y (the replacement node) to the node being deleted.
                // note: this effectively deletes the node.
                if (y != z)
                {
                    z.Key  = y.Key;
                    z.Data = y.Data;
                }

                if (y.Color == BLACK)
                {
                    RestoreAfterDelete(x, y.Parent);
                }

                lastNodeFound = null;

                intCount = intCount - 1;
            }
            catch (Exception e)
            {
                Console.WriteLine("RedBlackTree::RestoreAfterDelete threw " + e.Message);
            }
        }