public static RedBlackNode GetGrandparent(RedBlackNode grandchild) { if (_root == null) { return null; } return GetGrandparent(_root, grandchild); }
public static RedBlackNode GetParent(RedBlackNode child) { if (_root == null) { return null; } return GetParent(_root, child); }
/// <summary> /// java实现版本 /// </summary> /// <param name="key"></param> /// <returns></returns> public RedBlackNode <TKey, TValue> HeadNode1(TKey key) { RedBlackNode <TKey, TValue> p = rbTree; while (p != null) { int cmp = key.CompareTo(p.Key); if (cmp > 0) { if (p.Right != null) { p = p.Right; } else { return(p); } } else if (cmp < 0) { if (p.Left != null) { p = p.Left; } else { RedBlackNode <TKey, TValue> parent = p.Parent; RedBlackNode <TKey, TValue> ch = p; while (parent != null && ch == parent.Left) { ch = parent; parent = parent.Parent; } return(parent); } } else { return(p); } } return(null); }
///<summary> /// RotateRight /// Rebalance the tree by rotating the nodes to the right ///</summary> public void RotateRight(RedBlackNode <TKey, TValue> 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 <TKey, TValue> 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; } }
public static RedBlackNode GetUncle(RedBlackNode child) { if (_root == null) { return null; } RedBlackNode childsGrandparent = GetGrandparent(child); if (childsGrandparent != null) { if (child.Data < childsGrandparent.Data) { return childsGrandparent.Right; } return childsGrandparent.Left; } return null; }
///<summary> /// GetMaxKey /// Returns the maximum key value ///<summary> public TKey GetMaxKey() { RedBlackNode <TKey, TValue> treeNode = rbTree; if (treeNode == null || treeNode == sentinelNode) { throw (new RedBlackException("RedBlack tree is empty") { Error = ReadBlackCode.Empty }); } // traverse to the extreme right to find the largest key while (treeNode.Right != sentinelNode) { treeNode = treeNode.Right; } lastNodeFound = treeNode; return(treeNode.Key); }
/// <summary> /// 扩展一个方法 /// 是否包含Key /// </summary> /// <param name="key"></param> /// <returns></returns> public bool Contains(TKey key) { int result = -1; RedBlackNode <TKey, TValue> treeNode = rbTree; // begin at root // traverse tree until node is found while (treeNode != sentinelNode) { result = key.CompareTo(treeNode.Key); if (result == 0) { return(true); } if (result < 0) { treeNode = treeNode.Left; } else { treeNode = treeNode.Right; } } return(false); }
public static bool IsParent(RedBlackNode subTree, RedBlackNode child) { if (child.Data < subTree.Data) { if (subTree.Left.Data != -1 && subTree.Left.Data == child.Data) { return true; } } else if (subTree.Right.Data != -1 && subTree.Right.Data == child.Data) { return true; } return false; }
private static void DeleteCase1(RedBlackNode node) { if (GetParent(node).Data != -1) { DeleteCase2(node); } }
public static void ReplaceNode(RedBlackNode replacementNode, RedBlackNode oldNode) { RedBlackNode oldNodesParent = GetParent(oldNode); if (oldNodesParent == null) { _root = replacementNode; } else if (oldNodesParent.Left.Data == oldNode.Data) { oldNodesParent.Left = replacementNode; } else { oldNodesParent.Right = replacementNode; } }
private static void InsertCase5(RedBlackNode newSubTree) { RedBlackNode newSubTreesGrandparent = GetGrandparent(newSubTree); RedBlackNode newSubTreesParent = GetParent(newSubTree); newSubTreesParent.Color = RedBlackColorEnum.Black; newSubTreesGrandparent.Color = RedBlackColorEnum.Red; if (newSubTreesParent.Left.Data == newSubTree.Data) { RotateRight(newSubTreesGrandparent); } else { RotateLeft(newSubTreesGrandparent); } }
private static void RotateRight(RedBlackNode subTree) { RedBlackNode parent = GetParent(subTree); if (parent == null) { _root = subTree.Left; } subTree.Left.Right = subTree; if (parent != null) { if (parent.Left.Data == subTree.Data) { parent.Left = subTree.Left; } else { parent.Right = subTree.Left; } } subTree.Left = new RedBlackNode().NewEmptyNode(); }
private static void DeleteCase6(RedBlackNode node) { RedBlackNode sibling = GetSibling(node); RedBlackNode parent = GetParent(node); sibling.Color = parent.Color; parent.Color = RedBlackColorEnum.Black; if (node.Data == parent.Left.Data) { sibling.Right.Color = RedBlackColorEnum.Black; RotateLeft(parent); } else { sibling.Left.Color = RedBlackColorEnum.Black; RotateRight(parent); } }
public static bool IsLeaf(RedBlackNode node) { return (node.Right.Data == -1 && node.Left.Data == -1); }
private static void DeleteCase2(RedBlackNode node) { RedBlackNode sibling = GetSibling(node); RedBlackNode parent = GetParent(node); if (sibling.Color == RedBlackColorEnum.Red) { parent.Color = RedBlackColorEnum.Red; sibling.Color = RedBlackColorEnum.Black; if (node.Data == parent.Left.Data) { RotateLeft(parent); } else { RotateRight(parent); } } DeleteCase3(node); }
///<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 <TKey, TValue> x) { // maintain Red-Black tree balance after deleting node RedBlackNode <TKey, TValue> y; while (x != rbTree && x.Color == RedBlackNode <TKey, TValue> .BLACK) { if (x == x.Parent.Left) // determine sub tree from parent { y = x.Parent.Right; // y is x's sibling if (y.Color == RedBlackNode <TKey, TValue> .RED) { // x is black, y is red - make both black and rotate y.Color = RedBlackNode <TKey, TValue> .BLACK; x.Parent.Color = RedBlackNode <TKey, TValue> .RED; RotateLeft(x.Parent); y = x.Parent.Right; } if (y.Left.Color == RedBlackNode <TKey, TValue> .BLACK && y.Right.Color == RedBlackNode <TKey, TValue> .BLACK) { // children are both black y.Color = RedBlackNode <TKey, TValue> .RED; // change parent to red x = x.Parent; // move up the tree } else { if (y.Right.Color == RedBlackNode <TKey, TValue> .BLACK) { y.Left.Color = RedBlackNode <TKey, TValue> .BLACK; y.Color = RedBlackNode <TKey, TValue> .RED; RotateRight(y); y = x.Parent.Right; } y.Color = x.Parent.Color; x.Parent.Color = RedBlackNode <TKey, TValue> .BLACK; y.Right.Color = RedBlackNode <TKey, TValue> .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 <TKey, TValue> .RED) { y.Color = RedBlackNode <TKey, TValue> .BLACK; x.Parent.Color = RedBlackNode <TKey, TValue> .RED; RotateRight(x.Parent); y = x.Parent.Left; } if (y.Right.Color == RedBlackNode <TKey, TValue> .BLACK && y.Left.Color == RedBlackNode <TKey, TValue> .BLACK) { y.Color = RedBlackNode <TKey, TValue> .RED; x = x.Parent; } else { if (y.Left.Color == RedBlackNode <TKey, TValue> .BLACK) { y.Right.Color = RedBlackNode <TKey, TValue> .BLACK; y.Color = RedBlackNode <TKey, TValue> .RED; RotateLeft(y); y = x.Parent.Left; } y.Color = x.Parent.Color; x.Parent.Color = RedBlackNode <TKey, TValue> .BLACK; y.Left.Color = RedBlackNode <TKey, TValue> .BLACK; RotateRight(x.Parent); x = rbTree; } } } x.Color = RedBlackNode <TKey, TValue> .BLACK; }
/// <summary> /// 小于等于该Key(没有测试) /// </summary> /// <param name="key"></param> /// <returns></returns> public SortedDictionary <TKey, TValue> HeadMap(TKey key) { SortedDictionary <TKey, TValue> dic = new SortedDictionary <TKey, TValue>(); if (rbTree == null) { return(null); } if (minKey.CompareTo(key) > 0) { return(null); } RedBlackNode <TKey, TValue> treeNode = rbTree; // begin at root // traverse tree until node is found int result = -1; while (treeNode != sentinelNode) { result = key.CompareTo(treeNode.Key); if (result > 0) { break; } else { treeNode = treeNode.Left; } } //左右支路各一个线程查找;只能查找 var taskLeft = Task.Factory.StartNew(() => { LinkedList <RedBlackNode <TKey, TValue> > lstKeys = new LinkedList <RedBlackNode <TKey, TValue> >(); Func <TKey, bool> p = new Func <TKey, bool>((k) => { if (k.CompareTo(key) <= 0) { return(true); } else { return(false); } }); PreOrderNode(rbTree, lstKeys, p); return(lstKeys); }); var taskRight = Task.Factory.StartNew(() => { LinkedList <RedBlackNode <TKey, TValue> > lstKeys = new LinkedList <RedBlackNode <TKey, TValue> >(); Func <TKey, bool> p = new Func <TKey, bool>((k) => { if (k.CompareTo(key) <= 0) { return(true); } else { return(false); } }); PreOrderNode(rbTree.Right, lstKeys, p); return(lstKeys); }); // if (taskLeft.Result != null) { foreach (var item in taskLeft.Result) { dic[item.Key] = item.Value; } taskLeft.Result.Clear(); } if (taskRight.Result != null) { foreach (var item in taskRight.Result) { dic[item.Key] = item.Value; } taskRight.Result.Clear(); } return(dic); }
private static void DeleteCase4(RedBlackNode node) { RedBlackNode sibling = GetSibling(node); RedBlackNode parent = GetParent(node); if (parent.Color == RedBlackColorEnum.Red && sibling.Color == RedBlackColorEnum.Black && sibling.Left.Color == RedBlackColorEnum.Black && sibling.Right.Color == RedBlackColorEnum.Black) { sibling.Color = RedBlackColorEnum.Red; parent.Color = RedBlackColorEnum.Black; } else { DeleteCase5(node); } }
private static RedBlackNode GetParent(RedBlackNode subTree, RedBlackNode child) { if (child.Data < subTree.Data) { if (subTree.Left.Data != -1) { if (subTree.Left.Data == child.Data) { return subTree; } return GetParent(subTree.Left, child); } } else if (subTree.Right.Data != -1) { if (subTree.Right.Data == child.Data) { return subTree; } return GetParent(subTree.Right, child); } return null; }
private static RedBlackNode GetGrandparent(RedBlackNode subTree, RedBlackNode grandchild) { if (grandchild.Data < subTree.Data) { if (subTree.Left.Data != -1) { if (IsParent(subTree.Left, grandchild)) { return subTree; } return GetGrandparent(subTree.Left, grandchild); } } else if (subTree.Right.Data != -1) { if (IsParent(subTree.Right, grandchild)) { return subTree; } return GetGrandparent(subTree.Right, grandchild); } return null; }
private static RedBlackNode Find(RedBlackNode node, int data) { if (node.Data == data) { return node; } if (data < node.Data) { if (node.Left.Data != -1) { return Find(node.Left, data); } } else { if (node.Right.Data != -1) { return Find(node.Right, data); } } return null; }
public static bool HasLeaf(RedBlackNode node) { if (!IsLeaf(node)) { return (IsLeaf(node.Left) || IsLeaf(node.Right)); } return false; }
///<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(TKey key, TValue data) { if (key == null || data == null) { throw (new RedBlackException("RedBlackNode<TKey,TValue> key and data must not be null") { Error = ReadBlackCode.DataNull }); } // traverse tree - find where node belongs int result = 0; // create new node RedBlackNode <TKey, TValue> node = new RedBlackNode <TKey, TValue>(); RedBlackNode <TKey, TValue> 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") { Error = ReadBlackCode.KeyExists }); } if (result > 0) { temp = temp.Right; } else { temp = temp.Left; } // } // setup node node.Key = key; node.Value = 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 maxKey = minKey = key; minNode = new RedBlackNode <TKey, TValue>() { Key = minKey, Value = data }; maxNode = new RedBlackNode <TKey, TValue>() { Key = maxKey, Value = data }; } RestoreAfterInsert(node); // restore red-black properities lastNodeFound = node; intCount = intCount + 1; if (minKey.CompareTo(key) > 0) { minKey = key; minNode.Key = key; minNode.Value = data; } if (maxKey.CompareTo(key) < 0) { maxKey = key; maxNode.Key = key; maxNode.Value = data; } }
private static RedBlackNode GetSibling(RedBlackNode node) { RedBlackNode parent = GetParent(node); if (parent == null) { return null; } if (parent.Left.Data == node.Data) { return parent.Right; } return parent.Left; }
private static void DeleteCase5(RedBlackNode node) { RedBlackNode sibling = GetSibling(node); RedBlackNode parent = GetParent(node); if (sibling.Color == RedBlackColorEnum.Black) { if (node.Data == parent.Left.Data && sibling.Right.Color == RedBlackColorEnum.Black && sibling.Left.Color == RedBlackColorEnum.Red) { sibling.Color = RedBlackColorEnum.Red; sibling.Left.Color = RedBlackColorEnum.Black; RotateRight(sibling); } else if (node.Data == parent.Right.Data && sibling.Left.Color == RedBlackColorEnum.Black && sibling.Right.Color == RedBlackColorEnum.Red) { sibling.Color = RedBlackColorEnum.Red; sibling.Right.Color = RedBlackColorEnum.Black; RotateLeft(sibling); } } DeleteCase6(node); }
///<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 <TKey, TValue> x) { // x and y are used as variable names for brevity, in a more formal // implementation, you should probably change the names RedBlackNode <TKey, TValue> y; // maintain red-black tree properties after adding x while (x != rbTree && x.Parent.Color == RedBlackNode <TKey, TValue> .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 <TKey, TValue> .RED) { // uncle is red; change x's Parent and uncle to black x.Parent.Color = RedBlackNode <TKey, TValue> .BLACK; y.Color = RedBlackNode <TKey, TValue> .BLACK; // grandparent must be red. Why? Every red node that is not // a leaf has only black children x.Parent.Parent.Color = RedBlackNode <TKey, TValue> .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 <TKey, TValue> .BLACK; // make Parent black x.Parent.Parent.Color = RedBlackNode <TKey, TValue> .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 <TKey, TValue> .RED) { x.Parent.Color = RedBlackNode <TKey, TValue> .BLACK; y.Color = RedBlackNode <TKey, TValue> .BLACK; x.Parent.Parent.Color = RedBlackNode <TKey, TValue> .RED; x = x.Parent.Parent; } else { if (x == x.Parent.Left) { x = x.Parent; RotateRight(x); } x.Parent.Color = RedBlackNode <TKey, TValue> .BLACK; x.Parent.Parent.Color = RedBlackNode <TKey, TValue> .RED; RotateLeft(x.Parent.Parent); } } } rbTree.Color = RedBlackNode <TKey, TValue> .BLACK; // rbTree should always be black }
private static void Insert(RedBlackNode subTree, RedBlackNode newSubTree) { if (newSubTree.Data < subTree.Data) { if (subTree.Left.Data == -1) { subTree.Left = newSubTree; } else { Insert(subTree.Left, newSubTree); } } else { if (subTree.Right.Data == -1) { subTree.Right = newSubTree; } else { Insert(subTree.Right, newSubTree); } } }
private static void InsertCase1(RedBlackNode newSubTree) { if (GetParent(newSubTree) == null) { newSubTree.Color = RedBlackColorEnum.Black; } else { InsertCase2(newSubTree); } }
private static void InsertCase2(RedBlackNode newSubTree) { RedBlackNode newSubTreesParent = GetParent(newSubTree); if (newSubTreesParent.Color != RedBlackColorEnum.Black) { InsertCase3(newSubTree); } }
///<summary> /// Delete /// Delete a node from the tree and restore red black properties ///<summary> private void Delete(RedBlackNode <TKey, TValue> 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 <TKey, TValue> x = new RedBlackNode <TKey, TValue>(); // work node to contain the replacement node RedBlackNode <TKey, TValue> 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.Value = y.Value; } if (y.Color == RedBlackNode <TKey, TValue> .BLACK) { RestoreAfterDelete(x); } lastNodeFound = sentinelNode; UpdateBorder(z.Key);//更新边界 }
private static void InsertCase3(RedBlackNode newSubTree) { RedBlackNode newSubTreesGrandparent = GetGrandparent(newSubTree); if (newSubTreesGrandparent.Left.Color == RedBlackColorEnum.Red && newSubTreesGrandparent.Right.Color == RedBlackColorEnum.Red) { newSubTreesGrandparent.Left.Color = RedBlackColorEnum.Black; newSubTreesGrandparent.Right.Color = RedBlackColorEnum.Black; newSubTreesGrandparent.Color = RedBlackColorEnum.Red; InsertCase1(newSubTreesGrandparent); } else { InsertCase4(newSubTree); } }
///<summary> /// Clear /// Empties or clears the tree ///<summary> public void Clear() { rbTree = sentinelNode; intCount = 0; }
private static void InsertCase4(RedBlackNode newSubTree) { RedBlackNode newSubTreesGrandparent = GetGrandparent(newSubTree); RedBlackNode newSubTreesParent = GetParent(newSubTree); RedBlackNode newSubTreesUncle = GetUncle(newSubTree); if (newSubTreesParent.Color == RedBlackColorEnum.Red && newSubTreesUncle.Color == RedBlackColorEnum.Black) { if (newSubTreesParent.Right.Data == newSubTree.Data && newSubTreesGrandparent.Left.Data == newSubTreesParent.Data) { RotateLeft(newSubTreesParent); InsertCase5(newSubTreesParent); return; } if (newSubTreesParent.Left.Data == newSubTree.Data && newSubTreesGrandparent.Right.Data == newSubTreesParent.Data) { RotateRight(newSubTreesParent); InsertCase5(newSubTreesParent); return; } } InsertCase5(newSubTree); }
///<summary> /// NextElement ///</summary> public object NextElement() { if (stack.Count == 0) { throw(new RedBlackException("Element not found") { Error = ReadBlackCode.ElementNotFound }); } // 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 <TKey, TValue> node = (RedBlackNode <TKey, TValue>)stack.Peek(); //next node in sequence if (ascending) { if (node.Right == RedBlack <TKey, TValue> .sentinelNode) { // yes, top node is lowest node in subtree - pop node off stack RedBlackNode <TKey, TValue> tn = (RedBlackNode <TKey, TValue>)stack.Pop(); // peek at right node's parent // get rid of it if it has already been used while (HasMoreElements() && ((RedBlackNode <TKey, TValue>)stack.Peek()).Right == tn) { tn = (RedBlackNode <TKey, TValue>)stack.Pop(); } } else { // find the next items in the sequence // traverse to left; find lowest and push onto stack RedBlackNode <TKey, TValue> tn = node.Right; while (tn != RedBlack <TKey, TValue> .sentinelNode) { stack.Push(tn); tn = tn.Left; } } } else // descending, same comments as above apply { if (node.Left == RedBlack <TKey, TValue> .sentinelNode) { // walk the tree RedBlackNode <TKey, TValue> tn = (RedBlackNode <TKey, TValue>)stack.Pop(); while (HasMoreElements() && ((RedBlackNode <TKey, TValue>)stack.Peek()).Left == tn) { tn = (RedBlackNode <TKey, TValue>)stack.Pop(); } } else { // determine next node in sequence // traverse to left subtree and find greatest node - push onto stack RedBlackNode <TKey, TValue> tn = node.Left; while (tn != RedBlack <TKey, TValue> .sentinelNode) { stack.Push(tn); tn = tn.Right; } } } // the following is for .NET compatibility (see MoveNext()) Key = node.Key; Value = node.Value; // ******** testing only ******** try { parentKey = node.Parent.Key; // testing only } catch (Exception e) { object o = e; // stop compiler from complaining parentKey = default(TKey); } if (node.Color == 0) // testing only { Color = "Red"; } else { Color = "Black"; } // ******** testing only ******** if (keys) { return(node.Key); } else { return(node.Value); } //return keys == true ? node.Key : node.Data; }
public static void Insert(int number) { RedBlackNode newSubTree = new RedBlackNode().NewDataNode(number); if (_root == null) { _root = newSubTree; } else { Insert(_root, newSubTree); } InsertCase1(newSubTree); }