Пример #1
0
		///<summary>
		/// Determine order, walk the tree and push the nodes onto the stack
		///</summary>
		public RedBlackEnumerator(RedBlackNode tnode, bool keys, bool ascending) 
        {
			
			stack           = new Stack();
			this.keys       = keys;
			this.ascending  = ascending;
			
            // use depth-first traversal to push nodes into stack
            // the lowest node will be at the top of the stack
            if(ascending)
			{   // find the lowest node
				while(tnode != RedBlack.sentinelNode)
				{
					stack.Push(tnode);
					tnode = tnode.Left;
				}
			}
			else
			{
                // the highest node will be at top of stack
				while(tnode != RedBlack.sentinelNode)
				{
					stack.Push(tnode);
					tnode = tnode.Right;
				}
			}
			
		}
Пример #2
0
		public RedBlack() 
        {
            strIdentifier       = base.ToString() + rand.Next();
            intHashCode         = rand.Next();

            // set up the sentinel node. the sentinel node is the key to a successfull
            // implementation and for understanding the red-black tree properties.
            sentinelNode        = new RedBlackNode();
            sentinelNode.Left   = null;
            sentinelNode.Right  = null;
            sentinelNode.Parent = null;
            sentinelNode.Color  = RedBlackNode.BLACK;
            rbTree              = sentinelNode;
            lastNodeFound       = sentinelNode;
        }
Пример #3
0
		///<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 void Add(IComparable key, object data)
		{
			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 node	=	new RedBlackNode();
			RedBlackNode temp	=	rbTree;				// grab the rbTree node of the tree

			while(temp != sentinelNode)
			{	// find Parent
				node.Parent	= temp;
				result		=  key.CompareTo(temp.Key);
				if(result == 0)
					throw(new RedBlackException("A Node with the same key already exists"));
				if(result > 0)
					temp = temp.Right;
				else
					temp = temp.Left;
			}
			
            // setup node
			node.Key			=	key;
			node.Data			=	data;
            node.Left           =   sentinelNode;
			node.Right          =   sentinelNode;

			// insert node into tree starting at parent's location
			if(node.Parent != null)	
			{
				result	=  node.Key.CompareTo(node.Parent.Key);
				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;
		}
Пример #4
0
        // Rebalance the tree by rotating the nodes to the left
        public void RotateLeft(RedBlackNode x)
        {
            // pushing node x down and to the Left to balance the tree. x's Right child (y)
            // replaces x (since y > x), and y's Left child becomes x's Right child
            // (since it's < y but > x).

            RedBlackNode y = x.Right; // get x's Right node, this becomes y

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

            // modify parents
            if (y.Left != sentinelNode)
            {
                y.Left.Parent = x; // sets y's Left Parent to x
            }
            if (y != sentinelNode)
            {
                y.Parent = x.Parent; // set y's Parent to x's Parent
            }
            if (x.Parent != null)    // determine which side of it's Parent x was on
            {
                if (x == x.Parent.Left)
                {
                    x.Parent.Left = y; // set Left Parent to y
                }
                else
                {
                    x.Parent.Right = y; // set Right Parent to y
                }
            }
            else
            {
                rbTree = y; // at rbTree, set it to y
            }
            // link x and y
            y.Left = x;            // put x on y's Left
            if (x != sentinelNode) // set y as x's Parent
            {
                x.Parent = y;
            }
        }
Пример #5
0
    ///<summary>
    /// Get Specific Key
    /// Returns the specific key value
    ///<summary>
    public void RemoveAt(IComparable key)
    {
      RedBlackNode treeNode = rbTree;

      if (treeNode == null || treeNode == sentinelNode)
        throw (new RedBlackException("RedBlack tree is empty"));

      // traverse to find key node
      int result;            
      result = key.CompareTo(lastNodeFound.Key);
      if (result == 0)
        treeNode = lastNodeFound;
      else
      {	// not found, must search	
        while (treeNode != sentinelNode)
        {
          result = key.CompareTo(treeNode.Key);
          if (result == 0)
            break;
          if (result < 0)
            treeNode = treeNode.Left;
          else
            treeNode = treeNode.Right;
        }
        if (treeNode == sentinelNode)
          return;				// key not found
      }
      lastNodeFound = treeNode;
      
      Remove(treeNode.Key);
    }
Пример #6
0
		///<summary>
		/// GetMaxKey
		/// Returns the maximum key value
		///<summary>
		public IComparable GetMaxKey()
		{
			RedBlackNode treeNode = rbTree;
			
            if(treeNode == null || treeNode == sentinelNode)
                throw(new RedBlackException("RedBlack tree is empty"));

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

			lastNodeFound = treeNode;

			return treeNode.Key;
			
		}
Пример #7
0
		///<summary>
		/// GetData
		/// Gets the data object associated with the specified key
		///<summary>
		public object GetData(IComparable key)
		{
			int result;
			
            RedBlackNode treeNode = rbTree;     // begin at root
            
            // traverse tree until node is found
            while(treeNode != sentinelNode)
			{
				result = key.CompareTo(treeNode.Key);
				if(result == 0)
				{
					lastNodeFound = treeNode;
					return treeNode.Data;
				}
				if(result < 0)
					treeNode = treeNode.Left;
				else
					treeNode = treeNode.Right;
			}
			
			throw(new RedBlackException("RedBlackNode key was not found"));
		}
Пример #8
0
		///<summary>
		/// RotateRight
		/// Rebalance the tree by rotating the nodes to the right
		///</summary>
		public void RotateRight(RedBlackNode 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 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 != sentinelNode) 
				y.Right.Parent = x;				// sets y's Right Parent to x

            if(y != sentinelNode)
                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 != sentinelNode)				// set y as x's Parent
				x.Parent = y;		
		}		
Пример #9
0
        public long RedBlackVerify2(RedBlackNode root, long depth)
        {
            long height_left;
            long height_right;

            if (root == RedBlack.sentinelNode)
            {
                return 1;
            }

            height_left = RedBlackVerify2(root.Left, depth + 1);
            height_right = RedBlackVerify2(root.Right, depth + 1);

            if (height_left == 0 || height_right == 0)
            {
                return 0;
            }

            if (height_left != height_right)
            {
                Console.WriteLine("WARNING: Imbalance @depth={0} : {1} {2}\n", depth, height_left, height_right);
            }

            if (root.Left != RedBlack.sentinelNode && root.Left.Parent != root)
            {
                Console.WriteLine("lineage(?)\n");
            }
            if (root.Right != RedBlack.sentinelNode && root.Right.Parent != root)
            {
                Console.WriteLine("lineage(?)\n");
            }

            // Red-Black alternation
            if (root.Color == RedBlackNode.RED)
            {
                if (root.Left != RedBlack.sentinelNode && root.Left.Color != RedBlackNode.BLACK)
                {
                    Console.WriteLine("verify1(?)\n");
                    return 0;
                }
                if (root.Right != RedBlack.sentinelNode && root.Right.Color != RedBlackNode.BLACK)
                {
                    Console.WriteLine("verify2(?)\n");
                    return 0;
                }
                return height_left;
            }

            if (root.Color != RedBlackNode.BLACK)
            {
                Console.WriteLine("verify3(?)\n");
                return 0;
            }

            return (height_left + 1);
        }
Пример #10
0
 public void Clear()
 {
     rbTree   = sentinelNode;
     intCount = 0;
 }
Пример #11
0
        // Deletions from red-black trees may destroy the red-black
        // properties. Examine the tree and restore. Rotations are normally
        // required to restore it
        private void RestoreAfterDelete(RedBlackNode x)
        {
            RedBlackNode y;

            while (x != rbTree && x.Color == RedBlackNode.BLACK)
            {
                if (x == x.Parent.Left)              // determine sub tree from parent
                {
                    y = x.Parent.Right;              // y is x's sibling
                    if (y.Color == RedBlackNode.RED) // x is black, y is red - make both black and rotate
                    {
                        y.Color        = RedBlackNode.BLACK;
                        x.Parent.Color = RedBlackNode.RED;
                        RotateLeft(x.Parent);
                        y = x.Parent.Right;
                    }
                    if (y.Left.Color == RedBlackNode.BLACK &&
                        y.Right.Color == RedBlackNode.BLACK) // children are both black
                    {
                        y.Color = RedBlackNode.RED;          // change parent to red
                        x       = x.Parent;                  // move up the tree
                    }
                    else
                    {
                        if (y.Right.Color == RedBlackNode.BLACK)
                        {
                            y.Left.Color = RedBlackNode.BLACK;
                            y.Color      = RedBlackNode.RED;
                            RotateRight(y);
                            y = x.Parent.Right;
                        }
                        y.Color        = x.Parent.Color;
                        x.Parent.Color = RedBlackNode.BLACK;
                        y.Right.Color  = RedBlackNode.BLACK;
                        RotateLeft(x.Parent);
                        x = rbTree;
                    }
                }
                else // right subtree - same as code above with right and left swapped
                {
                    y = x.Parent.Left;
                    if (y.Color == RedBlackNode.RED)
                    {
                        y.Color        = RedBlackNode.BLACK;
                        x.Parent.Color = RedBlackNode.RED;
                        RotateRight(x.Parent);
                        y = x.Parent.Left;
                    }
                    if (y.Right.Color == RedBlackNode.BLACK &&
                        y.Left.Color == RedBlackNode.BLACK)
                    {
                        y.Color = RedBlackNode.RED;
                        x       = x.Parent;
                    }
                    else
                    {
                        if (y.Left.Color == RedBlackNode.BLACK)
                        {
                            y.Right.Color = RedBlackNode.BLACK;
                            y.Color       = RedBlackNode.RED;
                            RotateLeft(y);
                            y = x.Parent.Left;
                        }
                        y.Color        = x.Parent.Color;
                        x.Parent.Color = RedBlackNode.BLACK;
                        y.Left.Color   = RedBlackNode.BLACK;
                        RotateRight(x.Parent);
                        x = rbTree;
                    }
                }
            }
            x.Color = RedBlackNode.BLACK;
        }
Пример #12
0
        // Delete a node from the tree and restore red black properties
        private void Delete(RedBlackNode z)
        {
            // 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 x = new RedBlackNode(); // work node to contain the replacement node
            RedBlackNode y;                      // work node

            // find the replacement node (the successor to x) - the node one with
            // at *most* one child.
            if (z.Left == sentinelNode || z.Right == sentinelNode)
            {
                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 != sentinelNode) // 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 != sentinelNode)
            {
                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
            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 == RedBlackNode.BLACK)
            {
                RestoreAfterDelete(x);
            }

            lastNodeFound = sentinelNode;
        }
Пример #13
0
        // Additions to red-black trees usually destroy the red-black
        // properties. Examine the tree and restore. Rotations are normally
        // required to restore it.
        private void RestoreAfterInsert(RedBlackNode x)
        {
            // x and y are used as variable names for brevity, in a more formal
            // implementation, you should probably change the names
            RedBlackNode y;

            // maintain red-black tree properties after adding x
            while (x != rbTree && x.Parent.Color == RedBlackNode.RED)
            {
                // Parent node is .Colored red;
                // determine traversal path
                // is it on the Left or Right subtree?
                if (x.Parent == x.Parent.Parent.Left)
                {
                    y = x.Parent.Parent.Right; // get uncle

                    // // uncle is red; change x's Parent and uncle to black
                    if (y != null && y.Color == RedBlackNode.RED)
                    {
                        x.Parent.Color = RedBlackNode.BLACK;
                        y.Color        = RedBlackNode.BLACK;

                        // grandparent must be red. Why? Every red node that is not
                        // a leaf has only black children
                        x.Parent.Parent.Color = RedBlackNode.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        = RedBlackNode.BLACK; // make Parent black
                        x.Parent.Parent.Color = RedBlackNode.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 == RedBlackNode.RED)
                    {
                        x.Parent.Color        = RedBlackNode.BLACK;
                        y.Color               = RedBlackNode.BLACK;
                        x.Parent.Parent.Color = RedBlackNode.RED;
                        x = x.Parent.Parent;
                    }
                    else
                    {
                        if (x == x.Parent.Left)
                        {
                            x = x.Parent;
                            RotateRight(x);
                        }

                        x.Parent.Color        = RedBlackNode.BLACK;
                        x.Parent.Parent.Color = RedBlackNode.RED;
                        RotateLeft(x.Parent.Parent);
                    }
                }
            }

            rbTree.Color = RedBlackNode.BLACK; // rbTree should always be black
        }
Пример #14
0
 private RedBlackNode NodeSuccessor(RedBlackNode node)
 {
     if (node == RedBlack.sentinelNode)
         return RedBlack.sentinelNode;
     else if (node.Right != RedBlack.sentinelNode)
     {
         RedBlackNode p = node.Right;
         while (p.Left != RedBlack.sentinelNode)
         {
             p = p.Left;
         }
         return p;
     }
     else
     {
         RedBlackNode p = node.Parent;
         RedBlackNode ch = node;
         while (p != null && ch == p.Right)
         {
             ch = p;
             p = p.Parent;
         }
         return p;
     }
 }
Пример #15
0
 static RedBlack()
 {
     sentinelNode = new RedBlackNode();
 }
Пример #16
0
		///<summary>
		/// Delete
		/// Delete a node from the tree and restore red black properties
		///<summary>
		private void Delete(RedBlackNode z)
		{
			// 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 x = new RedBlackNode();	// work node to contain the replacement node
			RedBlackNode y;					// work node 

			// find the replacement node (the successor to x) - the node one with 
			// at *most* one child. 
			if(z.Left == sentinelNode || z.Right == sentinelNode) 
				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 != sentinelNode)		// 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 != sentinelNode)
                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
			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 == RedBlackNode.BLACK)
				RestoreAfterDelete(x);

			lastNodeFound = sentinelNode;
		}
Пример #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 x)
		{
			// maintain Red-Black tree balance after deleting node 			

			RedBlackNode y;

			while(x != rbTree && x.Color == RedBlackNode.BLACK) 
			{
				if(x == x.Parent.Left)			// determine sub tree from parent
				{
					y = x.Parent.Right;			// y is x's sibling 
					if(y.Color == RedBlackNode.RED) 
					{	// x is black, y is red - make both black and rotate
						y.Color			= RedBlackNode.BLACK;
						x.Parent.Color	= RedBlackNode.RED;
						RotateLeft(x.Parent);
						y = x.Parent.Right;
					}
					if(y.Left.Color == RedBlackNode.BLACK && 
						y.Right.Color == RedBlackNode.BLACK) 
					{	// children are both black
						y.Color = RedBlackNode.RED;		// change parent to red
						x = x.Parent;					// move up the tree
					} 
					else 
					{
						if(y.Right.Color == RedBlackNode.BLACK) 
						{
							y.Left.Color	= RedBlackNode.BLACK;
							y.Color			= RedBlackNode.RED;
							RotateRight(y);
							y				= x.Parent.Right;
						}
						y.Color			= x.Parent.Color;
						x.Parent.Color	= RedBlackNode.BLACK;
						y.Right.Color	= RedBlackNode.BLACK;
						RotateLeft(x.Parent);
						x = rbTree;
					}
				} 
				else 
				{	// right subtree - same as code above with right and left swapped
					y = x.Parent.Left;
					if(y.Color == RedBlackNode.RED) 
					{
						y.Color			= RedBlackNode.BLACK;
						x.Parent.Color	= RedBlackNode.RED;
						RotateRight (x.Parent);
						y = x.Parent.Left;
					}
					if(y.Right.Color == RedBlackNode.BLACK && 
						y.Left.Color == RedBlackNode.BLACK) 
					{
						y.Color = RedBlackNode.RED;
						x		= x.Parent;
					} 
					else 
					{
						if(y.Left.Color == RedBlackNode.BLACK) 
						{
							y.Right.Color	= RedBlackNode.BLACK;
							y.Color			= RedBlackNode.RED;
							RotateLeft(y);
							y				= x.Parent.Left;
						}
						y.Color			= x.Parent.Color;
						x.Parent.Color	= RedBlackNode.BLACK;
						y.Left.Color	= RedBlackNode.BLACK;
						RotateRight(x.Parent);
						x = rbTree;
					}
				}
			}
			x.Color = RedBlackNode.BLACK;
		}
Пример #18
0
        public object 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 node = (RedBlackNode)stack.Peek(); //next node in sequence

            if (ascending)
            {
                if (node.Right == RedBlack.sentinelNode)
                {
                    // yes, top node is lowest node in subtree - pop node off stack
                    RedBlackNode tn = (RedBlackNode)stack.Pop();

                    // peek at right node's parent
                    // get rid of it if it has already been used
                    while (HasMoreElements() && ((RedBlackNode)stack.Peek()).Right == tn)
                    {
                        tn = (RedBlackNode)stack.Pop();
                    }
                }
                else
                {
                    // find the next items in the sequence
                    // traverse to left; find lowest and push onto stack
                    RedBlackNode tn = node.Right;

                    while (tn != RedBlack.sentinelNode)
                    {
                        stack.Push(tn);
                        tn = tn.Left;
                    }
                }
            }
            else // descending, same comments as above apply
            {
                if (node.Left == RedBlack.sentinelNode)
                {
                    // walk the tree
                    RedBlackNode tn = (RedBlackNode)stack.Pop();
                    while (HasMoreElements() && ((RedBlackNode)stack.Peek()).Left == tn)
                    {
                        tn = (RedBlackNode)stack.Pop();
                    }
                }
                else
                {
                    // determine next node in sequence
                    // traverse to left subtree and find greatest node - push onto stack
                    RedBlackNode tn = node.Left;
                    while (tn != RedBlack.sentinelNode)
                    {
                        stack.Push(tn);
                        tn = tn.Right;
                    }
                }
            }

            Key   = node.Key;
            Value = node.Data;

            return(keys == true ? node.Key : node.Data);
        }
Пример #19
0
		///<summary>
		/// Clear
		/// Empties or clears the tree
		///<summary>
		public void Clear ()
		{
			rbTree      = sentinelNode;
			intCount    = 0;
		}
Пример #20
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 x)
		{   
            // x and y are used as variable names for brevity, in a more formal
            // implementation, you should probably change the names

			RedBlackNode y;

			// maintain red-black tree properties after adding x
			while(x != rbTree && x.Parent.Color == RedBlackNode.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 == RedBlackNode.RED)
					{	// uncle is red; change x's Parent and uncle to black
						x.Parent.Color			= RedBlackNode.BLACK;
						y.Color					= RedBlackNode.BLACK;
						// grandparent must be red. Why? Every red node that is not 
						// a leaf has only black children 
						x.Parent.Parent.Color	= RedBlackNode.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			= RedBlackNode.BLACK;	// make Parent black
						x.Parent.Parent.Color	= RedBlackNode.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 == RedBlackNode.RED)
					{
						x.Parent.Color			= RedBlackNode.BLACK;
						y.Color					= RedBlackNode.BLACK;
						x.Parent.Parent.Color	= RedBlackNode.RED;
						x						= x.Parent.Parent;
					}
					else
					{
						if(x == x.Parent.Left)
						{
							x = x.Parent;
							RotateRight(x);
						}
						x.Parent.Color			= RedBlackNode.BLACK;
						x.Parent.Parent.Color	= RedBlackNode.RED;
						RotateLeft(x.Parent.Parent);
					}
				}																													
			}
			rbTree.Color = RedBlackNode.BLACK;		// rbTree should always be black
		}