public BinaryNode <T> Remove(T value, Func <T, T, int> сompareTo) { var newRoot = this; if (сompareTo(value, Value) < 0) { LeftNode = RemoveFromParent(LeftNode, value, сompareTo); if (GetHeightDifference() == -2) { if (RightNode.GetHeightDifference() <= 0) { newRoot = RotateLeft(); } else { newRoot = RotateRightLeft(); } } } else if (сompareTo(value, Value) > 0) { RightNode = RemoveFromParent(RightNode, value, сompareTo); if (GetHeightDifference() == 2) { if (LeftNode.GetHeightDifference() >= 0) { newRoot = RotateRight(); } else { newRoot = RotateLeftRight(); } } } else { if (ReferenceEquals(LeftNode, null)) { return(RightNode); } var child = LeftNode; while (!ReferenceEquals(child.RightNode, null)) { return(child.RightNode); } var childIndex = child.Index; var childValue = child.Value; LeftNode = RemoveFromParent(LeftNode, childValue, сompareTo); Value = childValue; Index = childIndex; if (GetHeightDifference() == -2) { if (RightNode.GetHeightDifference() <= 0) { newRoot = RotateLeft(); } else { newRoot = RotateRightLeft(); } } } newRoot.ComputeHeight(); return(newRoot); }