Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Podcast Ch17d • Title: Drawing a Binary Tree • Description: Drawing a binary tree; building a shadow tree, the displayTree method • Participants: Barry Kurtz (instructor); John Helfert and Tobie Williams (students) • Textbook: Data Structures for Java; William H. Ford and William R. Topp Drawing a Binary Tree • The methods displayTree(), drawTree(), and drawTrees() display a binary tree as a string or graphically. The algorithms employ many of the basic features of a binary tree. Drawing a Binary Tree (continued) • View the display of the tree as a rectangular grid with a cell denoted by the pair (level, column). The level is a row in the grid corresponding to a level in the tree. The column coordinate designates a region of the display measured left to right. Drawing a Binary Tree (continued) Drawing a Binary Tree (continued) • The algorithm to display a tree is a two step process. 1. The first step uses the recursive function buildShadowTree() to carry out an inorder scan of the tree which creates a second tree, called a shadow tree. Its nodes store the value of the node in the original tree formatted as a string and the (level, col) position of the shadow tree node in the grid. 2. The second step performs a level order scan of the shadow tree to display the nodes. Building a Shadow Tree • As buildShadowTree() uses an inorder scan it moves from one grid column to another. For instance, with Tree 0, the order of visit is B D A E C. Note in the figure that this is the column-order for the nodes in the tree. Student Question • Carefully explain how BOTH the level and the column can be found from the inorder traversal Building a Shadow Tree (continued) • The nodes of a shadow tree are objects of type TNodeShadow. class TNodeShadow { public static int columnValue; public String nodeValueStr; public int level, column; public TNodeShadow left, right; public TNodeShadow () {} } Building a Shadow Tree (continued) • Each recursive call of buildShadowTree() allocates a TNodeShadow object and assigns it the node value string. It then makes recursive calls that create the left and right subtrees. • Each recursive call in the inorder scan creates a node in the column specified by the static value columnValue and then increments the variable for the next recursive call. buildShadowTree() // inorder scan used to build the shadow tree private static <T> TNodeShadow buildShadowTree(TNode<T> t, int level) { // reference to new shadow tree node TNodeShadow newNode = null; if (t != null) { // create the new shadow tree node newNode = new TNodeShadow(); // allocate node for left child at next level // in tree; attach node newNode.left = buildShadowTree(t.left, level+1); buildShadowTree() (concluded) // initialize variables of the new node // format conversion newNode.nodeValueStr = t.nodeValue.toString(); newNode.level = level; newNode.column = TNodeShadow.columnValue; // update column to next cell in the table TNodeShadow.columnValue++; // allocate node for right child at next level // in tree; attach node newNode.right = buildShadowTree(t.right, level+1); } return newNode; } Student Question • When displaying the shadow tree, what factors need to be taken into account to decide the proper indention before printing a node value? Displaying a Shadow Tree • The method displayTree() takes the root, t, of the binary tree as an argument and calls buildShadowTree() to create the shadow tree. // build the shadow tree TNodeShadow shadowRoot = buildShadowTree(t, 0); Displaying a Shadow Tree (cont) • Display the tree with a level order scan of the shadow tree. The scan uses the node data to position and display each node. col0 col1 col2 col3 col4 A level 0 level 1 level 2 B Cell (level, col) = (1,4) Indent 3*colWidth spaces from last node output. C D E // use for the level-order scan of the shadow tree LinkedQueue<TNodeShadow> q = new LinkedQueue<TNodeShadow>(); String displayStr = ""; int colWidth = maxCharacters + 1; int currLevel = 0, currCol = 0; // use during the level order scan of the shadow tree TNodeShadow currNode; displayTree() // return a string that displays a binary tree; // output of a node value requires no more than // maxCharacters public static <T> String displayTree(TNode<T> t, int maxCharacters) { // use for level-order scan of the shadow tree LinkedQueue<TNodeShadow> q = new LinkedQueue<TNodeShadow>(); String displayStr = ""; int colWidth = maxCharacters + 1; int currLevel = 0, currCol = 0; TNodeShadow.columnValue = 0; if (t == null) return displayStr; // build the shadow tree TNodeShadow shadowRoot = buildShadowTree(t, 0); displayTree() (continued) // use during level order scan of the shadow tree TNodeShadow currNode; // insert the root in the queue and set current // level to 0 q.push(shadowRoot); // continue the iterative process until the queue // is empty while(!q.isEmpty()) { // delete front node from queue and make it // the current node currNode = q.pop(); displayTree() (continued) // if level changes, output a newline if (currNode.level > currLevel) { currLevel = currNode.level; currCol = 0; displayStr += '\n'; } // if a left child exists, insert the child // in the queue if (currNode.left != null) q.push(currNode.left); // if a right child exists, insert the child // in the queue if (currNode.right != null) q.push(currNode.right); displayTree() (concluded) // output formatted node value if (currNode.column > currCol) { displayStr += formatChar(( currNode.column - currCol) * colWidth, ' '); currCol = currNode.column; } displayStr += formatString(colWidth, currNode.nodeValueStr); currCol++; } displayStr += '\n'; // delete the shadow tree shadowRoot = clearShadowTree(shadowRoot); return displayStr; } Student Question • How could this approach be adapted to draw a binary tree in a GUI interface so that the tree has branches displayed as well as node values?