// Program to test solutions to problem #8 on the cse143 final, winter 2023. // Fill in your solution to makeFull, then compile and run the program import java.util.*; class IntTree { public void makeFull() { // fill in your solution here and include any private methods below } private IntTreeNode overallRoot; // this is the sample solution public void makeFull2() { overallRoot = makeFull2(overallRoot, 1); } private IntTreeNode makeFull2(IntTreeNode root, int level) { if (root != null) { if (root.left == null && root.right != null) { root = new IntTreeNode(-level, root, root.right); root.left.right = null; } else if (root.left != null && root.right == null) { root = new IntTreeNode(-level, root.left, root); root.right.left = null; } root.left = makeFull2(root.left, level + 1); root.right = makeFull2(root.right, level + 1); } return root; } // post: constructs an empty tree public IntTree() { overallRoot = null; } // pre : the tree satisfies the binary search tree property // post: value is added so as to preserve the binary search tree property public void add(int value) { overallRoot = add(overallRoot, value); } // pre : the tree with given root satisfies the binary search tree property // post: value is added so as to preserve the binary search tree property private IntTreeNode add(IntTreeNode root, int value) { if (root == null) root = new IntTreeNode(value); else if (value <= root.data) root.left = add(root.left, value); else root.right = add(root.right, value); return root; } // post: prints the data fields of the tree, one per line, following // an inorder traversal and using indentation to indicate node depth; // prints right to left so that it looks correct when the output is // rotated. public void printStructure() { printStructure(overallRoot, 0); } // post: prints in preorder the data fields of the given tree indenting // each line to the given level private void printStructure(IntTreeNode root, int level) { if (root != null) { printStructure(root.right, level + 1); for (int i = 0; i < level; i++) System.out.print(" "); System.out.println(root.data); printStructure(root.left, level + 1); } } // returns true if this tree equals other tree public boolean equals(IntTree other) { return equals(overallRoot, other.overallRoot); } private boolean equals(IntTreeNode root1, IntTreeNode root2) { if (root1 == null || root2 == null) return root1 == null && root2 == null; else return root1.data == root2.data && equals(root1.left, root2.left) && equals(root1.right, root2.right); } } public class FinalTest8 { private static int testCount; private static int failCount; private static boolean tooManyNodes; public static final int ERRORS_MAX = 5; public static void main(String[] args) { for (int i = 0; i < 30; i++) test(i); if (failCount == 0) { System.out.println("passed all " + testCount + " tests"); } else { System.out.println("failed " + failCount + " of " + testCount + " tests"); } if (tooManyNodes) { System.out.println("Constructed too many nodes"); } } public static void test(int n) { IntTree t1 = new IntTree(); IntTree t2 = new IntTree(); Random r = new Random(); for (int i = 0; i < n; i++) { int next = r.nextInt(100); t1.add(next); t2.add(next); } System.out.println("Testing this tree:"); t1.printStructure(); System.out.println("Expected result:"); int oldCount = IntTreeNode.count; t1.makeFull2(); t1.printStructure(); int count2 = IntTreeNode.count - oldCount; oldCount = IntTreeNode.count; boolean fail = false; int count1 = 0; try { t2.makeFull(); count1 = IntTreeNode.count - oldCount; } catch (RuntimeException e) { System.out.println(" threw " + e); fail = true; } if (!fail && (!t1.equals(t2))) { System.out.println("actual result:"); t2.printStructure(); fail = true; } if (count1 != count2) { System.out.println("should have constructed " + count2 + " nodes"); System.out.println("actually constructed " + count1 + " nodes"); tooManyNodes = true; } testCount++; if (fail) { System.out.println("failed"); failCount++; if (failCount >= ERRORS_MAX) { System.out.println("----------------------------------------"); System.out.println("reached max " + ERRORS_MAX + " errors"); System.out.println("with " + testCount + " correct"); System.exit(0); } } else { System.out.println("passed"); } System.out.println("---------------------------------------------"); } } class IntTreeNode { public final int data; // data stored at this IntTreeNode public IntTreeNode left; // reference to left subtree public IntTreeNode right; // reference to right subtree public static int count; // post: constructs a leaf node with given data public IntTreeNode(int data) { this(data, null, null); } // post: constructs a IntTreeNode with the given data and links public IntTreeNode(int data, IntTreeNode left, IntTreeNode right) { this.data = data; this.left = left; this.right = right; count++; } }