private RbNode Insert(int key, int data, RbNode root) { RbNode parent = null; RbNode node = null; node = SearchAuxiliary(key, root, ref parent); if (node != null) { node.Data++; return(root); } node = CreateNode(key, data); node.Parent = parent; if (parent != null) { if (parent.Key > key) { parent.Left = node; } else { parent.Right = node; } } else { root = node; } return(InsertRebalance(node, root)); }
/// <summary> /// left rotate: ==> /// node right /// /\ /\ /// a right node y /// /\ /\ /// b y a b /// </summary> /// <param name="node"></param> /// <param name="root"></param> /// <returns></returns> private RbNode RotateLeft(RbNode node, RbNode root) { RbNode right = node.Right; if (node.Right == right.Left) { right.Left.Parent = node; } right.Left = node; if (right.Parent == node.Parent) { if (node == node.Parent.Right) { node.Parent.Right = right; } else { node.Parent.Left = right; } } else { root = right; } node.Parent = right; return(root); }
private RbNode SearchAuxiliary(int key, RbNode root, ref RbNode save) { RbNode node = root; RbNode parent = null; int ret; while (node != null) { parent = node; ret = node.Key - key; if (ret > 0) { node = node.Left; } else if (ret < 0) { node = node.Right; } else { return(node); } } if (parent != null) { save = parent; } return(null); }
/// <summary> /// right rotate ==> left /// node /\ /// /\ a node /// left y /\ /// /\ b y /// a b /// </summary> /// <param name="node"></param> /// <param name="root"></param> /// <returns></returns> private RbNode RotateRight(RbNode node, RbNode root) { RbNode left = node.Left; if (node.Left == left.Right) { left.Right.Parent = node; } left.Right = node; if (left.Parent == node.Parent) { if (node == node.Parent.Right) { node.Parent.Right = left; } else { node.Parent.Left = left; } } else { root = left; } node.Parent = left; return(root); }
private RbNode CreateNode(int key, int data) { RbNode node = new RbNode { Key = key, Data = data, Color = RbColor.Red }; return(node); }
private RbNode Search(int key, RbNode root) { RbNode parent = root; return(SearchAuxiliary(key, root, ref parent)); }
/// <summary> /// The 3 cases of red-black tree insertion /// z stands for current node, p[z] is parent, p[p[z]] is grandparent, y is uncle /// </summary> /// <param name="node"></param> /// <param name="root"></param> /// <returns></returns> private RbNode InsertRebalance(RbNode node, RbNode root) { RbNode parent, gparent, uncle, temp; while ((parent = node.Parent) != null && parent.Color == RbColor.Red) { gparent = parent.Parent; if (parent == gparent.Left) { uncle = gparent.Right; if (uncle != null && uncle.Color == RbColor.Red) { uncle.Color = RbColor.Black; parent.Color = RbColor.Black; gparent.Color = RbColor.Red; node = gparent; } else { if (parent.Right == node) { root = RotateLeft(parent, root); temp = parent; parent = node; node = temp; } parent.Color = RbColor.Black; gparent.Color = RbColor.Red; root = RotateRight(gparent, root); } } else { uncle = gparent.Left; if (uncle != null && uncle.Color == RbColor.Red) { uncle.Color = RbColor.Black; parent.Color = RbColor.Black; gparent.Color = RbColor.Red; node = gparent; } else { if (parent.Left == node) { root = RotateRight(parent, root); temp = parent; parent = node; node = temp; } parent.Color = RbColor.Black; gparent.Color = RbColor.Red; root = RotateLeft(gparent, root); } } } root.Color = RbColor.Black; return(root); }