public String toString() { int size = __getSize(); int height = __getHeight(); int widest = __getWidest() + 1; IntTreeNode.clearCycleData(20); String result = toString(overallRoot, 0, 0, size, height, widest); if (overallRoot == null) { result = "overallRoot\n null"; } else { String firstLine = ""; int nodesLeft = __getSize(overallRoot.left); if (overallRoot.left != null && (overallRoot.cycle() || overallRoot.left.cycle())) { // nodesLeft = 0; } int spaces = (nodesLeft * widest) - Math.max(0, "overallRoot".length() - widest + 1) / 2; for (int i = 0; i < spaces; i++) { firstLine += " "; } firstLine += "overallRoot\n"; int len = result.length(); while (len < firstLine.length()) { result = " " + result; len += 2; } result = firstLine + result; } return result; }
private int __getSize(IntTreeNode root) { if (root == null) { return 0; } else { int leftSize = 0; IntTreeNode left = root.__gotoLeft(); if (left != null && !left.cycle()) { leftSize = __getSize(left); } int rightSize = 0; IntTreeNode right = root.__gotoRight(); if (right != null && !right.cycle()) { rightSize = __getSize(right); } return (root.cycle() ? 0 : 1) + leftSize + rightSize; } }
private int __getHeight(IntTreeNode root) { if (root == null) { return 0; } else { int leftHeight = 0; IntTreeNode left = root.__gotoLeft(); if (left != null && !left.cycle()) { leftHeight = __getHeight(left); } int rightHeight = 0; IntTreeNode right = root.__gotoRight(); if (right != null && !right.cycle()) { rightHeight = __getHeight(right); } return (root.cycle() ? 0 : 1) + Math.max(leftHeight, rightHeight); } }
private int __getWidest(IntTreeNode root) { if (root == null) { return 0; } else { int width = root.toString().length(); int widestLeft = 0; IntTreeNode left = root.__gotoLeft(); if (left != null && !left.cycle()) { widestLeft = __getWidest(left); } int widestRight = 0; IntTreeNode right = root.__gotoRight(); if (right != null && !right.cycle()) { widestRight = __getWidest(right); } return Math.max(width, Math.max(widestLeft, widestRight)); } }
public IntTreeNode __gotoRight(boolean checkForCycle) { if (checkForCycle) { if (right != null) { if (right.visitsLeft > 0) { right.visitsLeft--; } if (right.cycle()) { // throw new IllegalStateException("cycle detected in tree"); } } } return right; }
private String toString( IntTreeNode root, int sizeAboveLeft, int level, int size, int height, int width) { // System.out.println("toString(root, " + sizeAboveLeft + ", " + level + ", " + size + ", " + // height + ", " + width + ")"); if (root == null) { return ""; } else { String result = ""; int sizeBelowLeft = __getSize(root.left); if (root.cycle()) { // sizeBelowLeft = 0; } int sizeLeft = sizeAboveLeft + sizeBelowLeft; // create line for this element // (must potentially put leading __ marks for left/right pointers) String thisElementLine = ""; String nextLine = ""; if (root.left == null) { // indent this node for (int i = 0; i < width * sizeAboveLeft; i++) { thisElementLine += " "; if (root.right != null) { nextLine += " "; } } } else { // indent this node, but insert / and _____ for left pointer int widthOfLeft = root.left.toString().length(); int dWidthLeft = width - widthOfLeft; int betweenLeft = __getSizeBetweenLeft(root); if (root.cycle()) { // betweenLeft = 0; } for (int i = 0; i < width * (sizeLeft - betweenLeft) - dWidthLeft; i++) { thisElementLine += " "; nextLine += " "; } thisElementLine += " "; nextLine += "/"; for (int i = 0; i < width * betweenLeft - 1 + dWidthLeft; i++) { thisElementLine += "_"; if (root.right != null) { nextLine += " "; } } } thisElementLine += root; if (root.right != null) { // insert _____ and \ for right pointer for (int i = 0; i < root.toString().length(); i++) { nextLine += " "; } for (int i = 0; i < width - root.toString().length() - 1; i++) { thisElementLine += "_"; nextLine += " "; } int betweenRight = root.cycle() ? 0 : __getSizeBetweenRight(root); for (int i = 0; i < width * betweenRight; i++) { thisElementLine += "_"; nextLine += " "; } nextLine += "\\"; } if (root.left == null && root.right == null) { result += thisElementLine; } else { thisElementLine += "\n"; nextLine += "\n"; // append all left elements String leftLines = root.cycle() ? "" : toString(root.__gotoLeft(), sizeAboveLeft, level + 1, size, height, width); // append all right elements String rightLines = root.cycle() ? "" : toString(root.__gotoRight(), sizeLeft + 1, level + 1, size, height, width); result += thisElementLine + nextLine + mergeLines(leftLines, rightLines); } return result; } }