public void GrandRotateTest(GrandRotateTestData grandRotateTestData) { int[] keys = grandRotateTestData.Keys; int rotationNodeKey = grandRotateTestData.RotationNodeKey; int heightAfterUpdate = grandRotateTestData.HeightAfterUpdate; ChildDirection direction = grandRotateTestData.direction; if (keys.Any()) { var root = keys.CreateTree(); var nodes = root.InOrderSearch().ToArray(); var rotationNode = nodes.FirstOrDefault(x => x.Key == rotationNodeKey); TreeNode newNode = null; if (direction == ChildDirection.Left) { newNode = rotationNode.GrandLeftRotate(); //operation } else if (direction == ChildDirection.Right) { newNode = rotationNode.GrandRightRotate(); //operation } var newRoot = nodes.Single(x => x.Parent == null); Assert.True(nodes.All(IsLinkCorrect)); Assert.Equal(keys.OrderBy(x => x).ToArray(), newRoot.InOrderSearch().Select(x => x.Key).ToArray()); newNode.UpdateHeights(); Assert.Equal(heightAfterUpdate, newRoot.InOrderSearch().Max(x => x.Height)); Assert.All(nodes, node => Assert.Equal(node.CalcHeight(), node.Height)); } }
public GrandRotateTestData(int[] keys, int rotationNodeKey, int heightAfterUpdate, ChildDirection direction) { Keys = keys; RotationNodeKey = rotationNodeKey; HeightAfterUpdate = heightAfterUpdate; this.direction = direction; }
private static bool AreExpressionTypesCollapsible(ExpressionType type, ExpressionType parentType, ChildDirection childDirection) { int num = BinaryPrecedence(type); int num2 = BinaryPrecedence(parentType); if ((num >= 0) && (num2 >= 0)) { if (childDirection == ChildDirection.Left) { if (num <= num2) { return true; } } else if (num < num2) { return true; } } return false; }
/// <summary> /// Visits operands for Binary and Unary expressions. /// Will only output parens if operand is complex expression, /// this is so don't have unecessary parens in URI. /// </summary> /// <param name="e">The operand expression to visit</param> /// <param name="parentType">The node type of the parent expression (if applicable)</param> /// <param name="childDirection">Indicates if the expression is to the left or the right of the parent expression</param> private void VisitOperand(Expression e, ExpressionType? parentType, ChildDirection? childDirection) { Debug.Assert( parentType.HasValue == childDirection.HasValue, "If a parent type is specified, a child direction must also be specified, or both must be unspecified."); if (e is BinaryExpression) { bool requiresParens = !parentType.HasValue || !AreExpressionTypesCollapsible(e.NodeType, parentType.Value, childDirection.Value); if (requiresParens) { this.builder.Append(UriHelper.LEFTPAREN); } this.Visit(e); if (requiresParens) { this.builder.Append(UriHelper.RIGHTPAREN); } } else { this.Visit(e); } }
/// <summary> /// Indicates if two expression types are collapsible, e.g., ((a or b) or c) can be collapsed to (a or b or c). /// </summary> /// <param name="type">The expression type</param> /// <param name="parentType">The expression type of the parent expression</param> /// <param name="childDirection">Indicates if the expression is to the left or the right of the parent expression</param> /// <returns>True if the two expression types are collapsible, false otherwise</returns> private static bool AreExpressionTypesCollapsible(ExpressionType type, ExpressionType parentType, ChildDirection childDirection) { int precedence = BinaryPrecedence(type); int parentPrecedence = BinaryPrecedence(parentType); // don't process if operators are not supported if (precedence >= 0 && parentPrecedence >= 0) { if (childDirection == ChildDirection.Left) { // Left nodes do not need parentheses if the precedence is equal or higher than the parent, e.g., // (1 + 2) + 3 => 1 + 2 + 3 // (1 * 2) + 3 => 1 * 2 + 3 if (precedence <= parentPrecedence) { return true; } } else { // Right nodes do not need parentheses if the precedence is higher than the parent if (precedence < parentPrecedence) { return true; } } } return false; }
/// <summary> /// Indicates if two expression types are collapsible, e.g., ((a or b) or c) can be collapsed to (a or b or c). /// </summary> /// <param name="type">The expression type</param> /// <param name="parentType">The expression type of the parent expression</param> /// <param name="childDirection">Indicates if the expression is to the left or the right of the parent expression</param> /// <returns>True if the two expression types are collapsible, false otherwise</returns> private static bool AreExpressionTypesCollapsible(ExpressionType type, ExpressionType parentType, ChildDirection childDirection) { int precedence = BinaryPrecedence(type); int parentPrecedence = BinaryPrecedence(parentType); // don't process if operators are not supported if (precedence >= 0 && parentPrecedence >= 0) { if (childDirection == ChildDirection.Left) { // Left nodes do not need parentheses if the precedence is equal or higher than the parent, e.g., // (1 + 2) + 3 => 1 + 2 + 3 // (1 * 2) + 3 => 1 * 2 + 3 if (precedence <= parentPrecedence) { return(true); } } else { // Right nodes do not need parentheses if the precedence is higher than the parent if (precedence < parentPrecedence) { return(true); } } } return(false); }
private static bool AreExpressionTypesCollapsible(ExpressionType type, ExpressionType parentType, ChildDirection childDirection) { int num = BinaryPrecedence(type); int num2 = BinaryPrecedence(parentType); if ((num >= 0) && (num2 >= 0)) { if (childDirection == ChildDirection.Left) { if (num <= num2) { return(true); } } else if (num < num2) { return(true); } } return(false); }
public FindResult(TreeNode parent, ChildDirection childDirection) { Parent = parent; ChildDirection = childDirection; }
private void VisitOperand(Expression e, ExpressionType? parentType, ChildDirection? childDirection) { if (e is BinaryExpression) { bool flag = !parentType.HasValue || !AreExpressionTypesCollapsible(e.NodeType, parentType.Value, childDirection.Value); if (flag) { this.builder.Append('('); } this.Visit(e); if (flag) { this.builder.Append(')'); } } else { this.Visit(e); } }