private static void goRight(ref Treap <Point> current, ref Point currentPoint, ref int toCut) { toCut = toCut + Treap <Point> .GetSize(current.Right.Left) + 1; current = current.Right; currentPoint = current.Key; }
private static void goLeft(ref Treap <Point> current, ref Point currentPoint, ref int toCut) { toCut = toCut - Treap <Point> .GetSize(current.Left.Right) - 1; current = current.Left; currentPoint = current.Key; }
public void SetConvexHull(bool isLeftHalf, Treap <Point> value) { if (isLeftHalf) { leftConvexHull = value; } else { rightConvexHull = value; } }
public Treap(T newKey, Treap <T> newLeft = null, Treap <T> newRight = null) { Key = newKey; Left = newLeft; Right = newRight; Size = 1; MaxElement = newKey; MinElement = newKey; update(); }
private static void pushSubHullDown(RedBlackNode current, bool isLeftHalf) { if (current != null && !current.IsLeaf && current.GetConvexHull(isLeftHalf) != null) { Treap <Point> leftHalf; Treap <Point> rightHalf; Treap <Point> .SplitBySize(current.GetConvexHull(isLeftHalf), current.GeLowerSubHullSize(isLeftHalf), out leftHalf, out rightHalf); current.Left.SetConvexHull(isLeftHalf, Treap <Point> .Merge(leftHalf, current.Left.GetConvexHull(isLeftHalf))); current.Right.SetConvexHull(isLeftHalf, Treap <Point> .Merge(current.Right.GetConvexHull(isLeftHalf), rightHalf)); current.SetConvexHull(isLeftHalf, null); } }
private RedBlackNode(Point newPoint = null, RedBlackNode newLeft = null, RedBlackNode newRight = null, RedBlackNode newParent = null) { Left = newLeft; Right = newRight; Parent = newParent; MaxPoint = newPoint; NodeColor = IsRoot ? Color.Black : Color.Red; leftConvexHull = null; leftLowerSubHullSize = 0; rightConvexHull = null; rightLowerSubHullSize = 0; }
public static bool IsValid(Treap <Point> hull) { if (hull == null) { return(true); } var list = hull.GetArray(); for (int i = 0; i < list.Count - 2; ++i) { if (DeterminePosition(list[i], list[i + 2], list[i + 1]) == PointPosition.Right) { return(false); } } return(true); }
public static void SplitBySize(Treap <T> current, int toCut, out Treap <T> leftHalf, out Treap <T> rightHalf) { if (current == null) { leftHalf = null; rightHalf = null; } else if (GetSize(current.Left) >= toCut) { SplitBySize(current.Left, toCut, out leftHalf, out rightHalf); current.Left = rightHalf; current.update(); rightHalf = current; } else { SplitBySize(current.Right, toCut - GetSize(current.Left) - 1, out leftHalf, out rightHalf); current.Right = leftHalf; current.update(); leftHalf = current; } }
public static Treap <T> Merge(Treap <T> leftTreap, Treap <T> rightTreap) { if (leftTreap == null) { return(rightTreap); } if (rightTreap == null) { return(leftTreap); } if (randomGenerator.Next(0, leftTreap.Size + rightTreap.Size) < leftTreap.Size) { leftTreap.Right = Merge(leftTreap.Right, rightTreap); leftTreap.update(); return(leftTreap); } else { rightTreap.Left = Merge(leftTreap, rightTreap.Left); rightTreap.update(); return(rightTreap); } }
public static int GetSize(Treap <T> treap) { return(treap == null ? 0 : treap.Size); }
private static void recount(RedBlackNode current, bool isLeftHalf) { if (current != null && current.Left != null && current.Right != null && current.GetConvexHull(isLeftHalf) == null) { current.MaxPoint = Utils.Max(current.Left.MaxPoint, current.Right.MaxPoint); Treap <Point> lowerCurrent = current.Left.GetConvexHull(isLeftHalf); Treap <Point> upperCurrent = current.Right.GetConvexHull(isLeftHalf); Point loweCurrentPoint = lowerCurrent.Key; Point upperCurrentPoint = upperCurrent.Key; double mediumY = (lowerCurrent.MaxElement.Y + upperCurrent.MinElement.Y) / 2; int toCutFromLowerHull = Treap <Point> .GetSize(lowerCurrent?.Left) + 1; int toLeaveInUpperHull = Treap <Point> .GetSize(upperCurrent?.Left) + 1; bool bridgeFound = false; while (!bridgeFound) { Point lowerPrevPoint = lowerCurrent?.Left != null ? lowerCurrent.Left.MaxElement : null; Point lowerNextPoint = lowerCurrent?.Right != null ? lowerCurrent.Right.MinElement : null; Point upperPrevPoint = upperCurrent?.Left != null ? upperCurrent.Left.MaxElement : null; Point upperNextPoint = upperCurrent?.Right != null ? upperCurrent.Right.MinElement : null; bridgeFound = makeDecisionAboutRotation(ref lowerCurrent, ref loweCurrentPoint, lowerPrevPoint, lowerNextPoint, ref toCutFromLowerHull, ref upperCurrent, ref upperCurrentPoint, upperPrevPoint, upperNextPoint, ref toLeaveInUpperHull, mediumY, isLeftHalf); } // we want to have top point in right treap after split --toLeaveInUpperHull; Treap <Point> leftPartOfLowerHull; Treap <Point> rightPartOfLowerHull; Treap <Point> leftPartOfUpperHull; Treap <Point> rightPartOfUpperHull; if (loweCurrentPoint.Y == upperCurrentPoint.Y) { if ((loweCurrentPoint.X < upperCurrentPoint.X && isLeftHalf) || (loweCurrentPoint.X > upperCurrentPoint.X && !isLeftHalf)) { ++toLeaveInUpperHull; } else if ((loweCurrentPoint.X > upperCurrentPoint.X && isLeftHalf) || (loweCurrentPoint.X < upperCurrentPoint.X && !isLeftHalf)) { --toCutFromLowerHull; } else { toLeaveInUpperHull++; } } current.SetLowerSubHullSize(isLeftHalf, toCutFromLowerHull); Treap <Point> .SplitBySize(current.Left.GetConvexHull(isLeftHalf), toCutFromLowerHull, out leftPartOfLowerHull, out rightPartOfLowerHull); Treap <Point> .SplitBySize(current.Right.GetConvexHull(isLeftHalf), toLeaveInUpperHull, out leftPartOfUpperHull, out rightPartOfUpperHull); current.SetConvexHull(isLeftHalf, Treap <Point> .Merge(leftPartOfLowerHull, rightPartOfUpperHull)); current.Left.SetConvexHull(isLeftHalf, rightPartOfLowerHull); current.Right.SetConvexHull(isLeftHalf, leftPartOfUpperHull); } }
private static bool makeDecisionAboutRotation(ref Treap <Point> lowerCurrent, ref Point lowerCurrentPoint, Point lowerPrevPoint, Point lowerNextPoint, ref int toCutFromLowerHull, ref Treap <Point> upperCurrent, ref Point upperCurrentPoint, Point upperPrevPoint, Point upperNextPoint, ref int toLeaveInUpperHull, double mediumY, bool isLeftHalf) { PointPosition lowerPrevPos = determinePosition(lowerCurrentPoint, upperCurrentPoint, lowerPrevPoint, isLeftHalf); PointPosition lowerNextPos = determinePosition(lowerCurrentPoint, upperCurrentPoint, lowerNextPoint, isLeftHalf); PointPosition upperPrevPos = determinePosition(lowerCurrentPoint, upperCurrentPoint, upperPrevPoint, isLeftHalf); PointPosition upperNextPos = determinePosition(lowerCurrentPoint, upperCurrentPoint, upperNextPoint, isLeftHalf); if (lowerPrevPos == PointPosition.Right && lowerNextPos == PointPosition.Right && upperPrevPos == PointPosition.Right && upperNextPos == PointPosition.Right) // A - found { return(true); // answer found } else if (lowerPrevPos == PointPosition.Left && lowerNextPos == PointPosition.Right && upperPrevPos == PointPosition.Right && upperNextPos == PointPosition.Right) // B { goLeft(ref lowerCurrent, ref lowerCurrentPoint, ref toCutFromLowerHull); //goRight(ref rightTop, ref rightTopPoint, ref rightMinPoint, ref rightMaxPoint, // ref toLeaveInRightHull, ref minPointLeaveInRight, ref maxPointLeaveInRight); } else if (lowerPrevPos == PointPosition.Right && lowerNextPos == PointPosition.Left && upperPrevPos == PointPosition.Right && upperNextPos == PointPosition.Right) // C { goRight(ref lowerCurrent, ref lowerCurrentPoint, ref toCutFromLowerHull); //goRight(ref rightTop, ref rightTopPoint, ref rightMinPoint, ref rightMaxPoint, // ref toLeaveInRightHull, ref minPointLeaveInRight, ref maxPointLeaveInRight); } else if (lowerPrevPos == PointPosition.Right && lowerNextPos == PointPosition.Right && upperPrevPos == PointPosition.Right && upperNextPos == PointPosition.Left) // D { //goLeft(ref leftTop, ref leftTopPoint, ref leftMinPoint, ref leftMaxPoint, // ref toCutFromLeftHull, ref minPointCutFromLeft, ref maxPointCutFromLeft); goRight(ref upperCurrent, ref upperCurrentPoint, ref toLeaveInUpperHull); } else if (lowerPrevPos == PointPosition.Right && lowerNextPos == PointPosition.Right && upperPrevPos == PointPosition.Left && upperNextPos == PointPosition.Right) // E { //goLeft(ref leftTop, ref leftTopPoint, ref leftMinPoint, ref leftMaxPoint, // ref toCutFromLeftHull, ref minPointCutFromLeft, ref maxPointCutFromLeft); goLeft(ref upperCurrent, ref upperCurrentPoint, ref toLeaveInUpperHull); } else if (lowerPrevPos == PointPosition.Left && lowerNextPos == PointPosition.Right && upperPrevPos == PointPosition.Right && upperNextPos == PointPosition.Left) // F { goLeft(ref lowerCurrent, ref lowerCurrentPoint, ref toCutFromLowerHull); goRight(ref upperCurrent, ref upperCurrentPoint, ref toLeaveInUpperHull); } else if (lowerPrevPos == PointPosition.Left && lowerNextPos == PointPosition.Right && upperPrevPos == PointPosition.Left && upperNextPos == PointPosition.Right) // G { goLeft(ref lowerCurrent, ref lowerCurrentPoint, ref toCutFromLowerHull); } else if (lowerPrevPos == PointPosition.Right && lowerNextPos == PointPosition.Left && upperPrevPos == PointPosition.Right && upperNextPos == PointPosition.Left) // H { goRight(ref upperCurrent, ref upperCurrentPoint, ref toLeaveInUpperHull); } else if (lowerPrevPos == PointPosition.Right && lowerNextPos == PointPosition.Left && upperPrevPos == PointPosition.Left && upperNextPos == PointPosition.Right) // I - the hardest { if (isIntersectLoverY(lowerCurrentPoint, lowerNextPoint, upperCurrentPoint, upperPrevPoint, mediumY, isLeftHalf)) { goRight(ref lowerCurrent, ref lowerCurrentPoint, ref toCutFromLowerHull); } else { goLeft(ref upperCurrent, ref upperCurrentPoint, ref toLeaveInUpperHull); } } else { throw new Exception("something wrong"); } return(false); // answer not found }
public RedBlackNode(Point newPoint, RedBlackNode newParent = null) : this(newPoint, null, null, newParent) { leftConvexHull = new Treap <Point>(newPoint); rightConvexHull = new Treap <Point>(newPoint); }