import java.util.List; import java.util.ArrayList; /** Bulk loads a binary search tree. @author Jed Yang Helper functions for printing trees from Anna Rafferty. */ public class BulkTree { private static class BinaryTreeNode { private int item; private BinaryTreeNode leftChild; private BinaryTreeNode rightChild; /** Returns the item represented by this node. */ public String toString() { return "" + item; } } // The root of this BulkTree private BinaryTreeNode root; /** Returns the height of the final tree. */ private int height(int n) { int height = 1; int power = 2; while (power < n+1) { height++; power *= 2; } return height; } /** Returns largest i such that 2^i divides n. */ private int row(int n) { int row = 0; int power = 2; while (n % power == 0) { row++; power *= 2; } return row; } /** Constructs a binary search tree with entries 1 through n. @param n */ public BulkTree(int n) { int height = height(n); System.out.println(height); BinaryTreeNode[] lastInRow = new BinaryTreeNode[height]; for (int i = 1; i <= n; i++) { int row = row(i); System.out.println(i + ":" + row); BinaryTreeNode newNode = new BinaryTreeNode(); newNode.item = i; // unless leaf, point down to last in row below if (row > 0) newNode.leftChild = lastInRow[row-1]; // look at row above, if last in row doesn't have right child, I'm it if (row < height - 1 && lastInRow[row+1] != null && lastInRow[row+1].rightChild == null) lastInRow[row+1].rightChild = newNode; // I'm now last in my row lastInRow[row] = newNode; } root = lastInRow[height-1]; for (int parent = height-1; parent > 0; parent--) { if (lastInRow[parent].rightChild != null) continue; // no rightChild; look for the tallest orphan int child = parent-1; // only something in lastInRow could be an orphan // it also should be bigger than parent while (child >= 0 && lastInRow[child].item < lastInRow[parent].item) { child--; } // adopt this child if (child >= 0) { lastInRow[parent].rightChild = lastInRow[child]; System.out.println(lastInRow[parent] + " adopted " + lastInRow[child]); } // try "21" to see double adoption // try "85" to see triple adoption } } /** Displays an ASCII-art sort of representation of this tree (image-like text). */ public void printTree() { printNode(root); } public static void main(String[] args) { BulkTree tree = new BulkTree(Integer.parseInt(args[0])); tree.printTree(); } /*************************************************************************** * You can (and should, for now) ignore all code below this point! * This code takes care of printing. * * Lightly modified from user post on stack overflow: * http://stackoverflow.com/questions/4965335/how-to-print-binary-tree-diagram */ private static void printNode(BinaryTreeNode root) { int maxLevel = maxLevel(root); List rootList = new ArrayList(); rootList.add(root); printNodeInternal(rootList, 1, maxLevel); } private static void printNodeInternal(List nodes, int level, int maxLevel) { if (nodes.isEmpty() || areAllElementsNull(nodes)) { return; } int floor = maxLevel - level; int edgeLines = (int) Math.pow(2, (Math.max(floor - 1, 0))); int firstSpaces = (int) Math.pow(2, (floor)) - 1; int betweenSpaces = (int) Math.pow(2, (floor + 1)) - 1; printWhitespaces(firstSpaces); List newNodes = new ArrayList(); for (BinaryTreeNode node : nodes) { if (node != null) { System.out.print(node.item); newNodes.add(node.leftChild); newNodes.add(node.rightChild); } else { newNodes.add(null); newNodes.add(null); System.out.print(" "); } printWhitespaces(betweenSpaces); } System.out.println(""); for (int i = 1; i <= edgeLines; i++) { for (int j = 0; j < nodes.size(); j++) { printWhitespaces(firstSpaces - i); if (nodes.get(j) == null) { printWhitespaces(edgeLines + edgeLines + i + 1); continue; } if (nodes.get(j).leftChild != null) System.out.print("/"); else printWhitespaces(1); printWhitespaces(i + i - 1); if (nodes.get(j).rightChild != null) System.out.print("\\"); else printWhitespaces(1); printWhitespaces(edgeLines + edgeLines - i); } System.out.println(""); } printNodeInternal(newNodes, level + 1, maxLevel); } private static void printWhitespaces(int count) { for (int i = 0; i < count; i++) System.out.print(" "); } private static int maxLevel(BinaryTreeNode node) { if (node == null) { return 0; } return Math.max(maxLevel(node.leftChild), maxLevel(node.rightChild)) + 1; } private static boolean areAllElementsNull(List list) { for (BinaryTreeNode object : list) { if (object != null) return false; } return true; } }