package aud.exam.prep.tree; import aud.exam.prep.Pointer; import java.util.Comparator; public class RecursiveOrderedBinaryTreeNodeProcessor extends OrderedBinaryTreeNodeProcessor { @Override public boolean find(BinaryTreeNode tree, V v, Comparator cmp) { return false; } @Override public boolean override(Pointer> pointer, V from, V to, Comparator cmp) { return false; } @Override public boolean overrideAll(Pointer> pointer, V from, V to, Comparator cmp) { return false; } @Override public BinaryTreeNode insert(BinaryTreeNode tree, V v, Comparator cmp) { if (tree == null) { tree = new BinaryTreeNode<>(); tree.key = v; return tree; } var c = cmp.compare(v, tree.key); if (c < 0 || c == 0 && tree.right != null) { tree.left = insert(tree.left, v, cmp); } else { tree.right = insert(tree.right, v, cmp); } return tree; } @Override public boolean remove(Pointer> pointer, V v, Comparator cmp) { var tree = pointer.deref; if (tree == null) { return false; } var c = cmp.compare(v, tree.key); if (c == 0) { if (tree.left == null) { pointer.deref = tree.right; } else if (tree.right == null) { pointer.deref = tree.left; } else { tree.key = getReplacementForRemoval(tree.left, tree, false); } return true; } if (c < 0) { return removeRec(tree.left, v, cmp, tree, false); } return removeRec(tree.right, v, cmp, tree, true); } private boolean removeRec(BinaryTreeNode node, V v, Comparator cmp, BinaryTreeNode prev, boolean right) { if (node == null) { return false; } var c = cmp.compare(v, node.key); if (c == 0) { if (node.left == null) { if (right) { prev.right = node.right; } else { prev.left = node.right; } } else if (node.right == null) { if (right) { prev.right = node.left; } else { prev.left = node.left; } } else { node.key = getReplacementForRemoval(node.left, node, false); } return true; } if (c < 0) { return removeRec(node.left, v, cmp, node, false); } return removeRec(node.right, v, cmp, node, true); } private V getReplacementForRemoval(BinaryTreeNode node, BinaryTreeNode prev, boolean right) { if (node.right == null) { if (right) { prev.right = node.left; } else { prev.left = node.left; } return node.key; } return getReplacementForRemoval(node.right, node, true); } @Override public boolean removeAll(Pointer> tree, V v, Comparator cmp) { return false; } @Override public V max(BinaryTreeNode tree) { if (tree == null) { throw new IllegalArgumentException("An empty tree has no max"); } if (tree.right == null) { return tree.key; } return max(tree.right); } @Override public V secondMax(BinaryTreeNode tree) { if (tree == null) { throw new IllegalArgumentException("An empty tree has no second max"); } if (tree.right != null) { return secondMaxRec(tree.right, tree.key); } if (tree.left != null) { return max(tree.left); } throw new IllegalArgumentException("A tree with only one element has no second max"); } private V secondMaxRec(BinaryTreeNode node, V prev) { if (node.right != null) { return secondMaxRec(node.right, node.key); } if (node.left != null) { return max(node.left); } return prev; } @Override public int height(BinaryTreeNode tree) { if (tree == null) { return -1; } return 0; } @Override public boolean isBalanced(BinaryTreeNode tree) { if (tree == null) { return true; } return false; } @Override public int numberOfNodes(BinaryTreeNode tree) { return 0; } @Override public int numberOfNodesOnLevel(BinaryTreeNode tree, int level) { return 0; } @Override public BinaryTreeNode rightmostNodeInLeftSubtree(BinaryTreeNode tree) { return null; } @Override public BinaryTreeNode leftmostNodeInRightSubtree(BinaryTreeNode tree) { return null; } @Override public BinaryTreeNode invert(BinaryTreeNode tree) { return null; } @Override public BinaryTreeNode clone(BinaryTreeNode tree) { return null; } @Override public boolean check(BinaryTreeNode tree, Comparator cmp) { if (tree == null) { return true; } if (tree.key == null) { return false; } if (tree.left != null) { if (!check(tree.left, cmp) || cmp.compare(tree.left.key, tree.key) > 0) { return false; } } if (tree.right != null) { return check(tree.right, cmp) && cmp.compare(tree.right.key, tree.key) >= 0; } return true; } }