12.07.2015 Views

BINARY SEARCH TREE VISUALIZATION ALGORITHM

BINARY SEARCH TREE VISUALIZATION ALGORITHM

BINARY SEARCH TREE VISUALIZATION ALGORITHM

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

<strong>BINARY</strong> <strong>SEARCH</strong> <strong>TREE</strong> <strong>VISUALIZATION</strong> <strong>ALGORITHM</strong>Vadym Borovskiy, Jürgen Müller, Matthieu-Patrick Schapranow, Alexander ZeierHasso Plattner Institute for Software Systems Engineering{vadym.borovskiy, juergen.mueller, matthieu.schapranow, alexander.zeier}@hpi.uni-potsdam.deKeywords:Abstract:Binary search tree, tree visualizationBinary search tree is a very common data structure in computer programming. Working with large BSTs canbecome complicated and inefficient unless a programmer can visualize them. This article contributes with twoBST visualization algorithms that draw a tree in time linearly proportional to the number of nodes in a tree.1 INTRODUCTIONMany tasks require a programmer to organize data incollections and perform different operations on thesecollections. Moreover, the collections and the operationsmust often be designed in a way that guaranteescertain parameters of program execution, for examplespeed and memory consumption. Because workingwith data collections or sets is so frequently encounteredexercise, a number of attempts has been madeto standardize these exercises and, thus, reduce thetime and effort of their implementation. For this reasonsmany standard data structures and algorithms appeared.Using these well-defined data structures andalgorithms 1 programmers can quickly and efficientlysolve various tasks.One of the standard data structures that has beenwidely used in programming is the tree data structure.Tree structure means a ”branching” relationshipbetween nodes (Knuth, 1973) and imposes a hierarchicalstructure on the collection of items. There aremany types of trees: binary trees, balanced trees, 2-3-trees, B-trees, red-black trees, Fibonacci trees, AVLtrees to name just a few. Each type of the tree datastructure has been designed to support a specific setof properties essential in a given situation.Tree structures are the most important nonlinearstructures that arise in computer algorithms (Knuth,1 or their modifications developed to handle specific requirements1973). Trees have numerous applications. They areused to analyze electrical circuits, to represent thestructure of mathematical formulas, to organize informationin database systems, to present the syntacticstructure of source programs in compilers and manyothers (Aho et al., 1983).In our last project we required to perform a complicatedanalysis of data supplied by experts. In thecore of analysis algorithm were Search, Minimum,Maximum, Insert and Delete operations on a collectionof integers of size up to 5000 items. The efficiencyof the main analysis algorithm greatly dependedon the efficiency of the aforementioned operations.We also had a requirement of implementing thisanalysis algorithm in a flexible way that will minimizethe effort of migrating it to other platforms (originallywe used .NET, but the execution environment couldchange to Win32 C++ or Java). The last requirementgreatly limited the choice of implementation tools. Inparticular, we could not use any platform-specific datatypes and design techniques. Therefore, we decidedto implement our own data type that will guaranteethe required efficiency of the above operations. Theimplementation was allowed to use only basic programmingconstructs (like for-loops, 4-byte integers,UNICODE strings and so on), which could easily beported to other environments.After reviewing classical data structures and algorithmswe decided to use the binary search tree datastructure as a prototype of the collection that our analysisalgorithm would operate on. A binary search tree


(BST) is a tree with keys which are always storedin a way that satisfies the binary-search-tree property(Cormen et al., 2001): If y is a node in the left subtreeof node x, then the key of y is less than or equal to thekey of x. If y is in the right subtree of x, then the keyof y is greater than or equal to the key of x.Having implemented the collection and the basicoperations on the collection we started developing ouranalysis algorithm on top of those. Very soon we experiencedthat working with a big BST can becomecumbersome unless a developer has a visual representationof the tree. In fact, when a tree became too big(more than 3000 nodes) we could not debug the analysisalgorithm efficiently because we simply lost trackof where we were in a tree. Hence, we arrived at thechallenge of visualizing BSTs on which the analysisalgorithm worked. The desired algorithm had to besimple, easy to port to other execution environmentsand efficient for large trees.In this article we present two methods of drawinga binary search tree. The article is structured asfollows. The section 2 names other approaches totree/graph visualization. The section 3 lists all theassumptions we made about BSTs to draw and contributeswith two ways of drawing a BST.2 RELATED WORKA tree is an acyclic graph. Therefore, graph visualizationtools can be used to draw a BST.Graphviz 2 - is open source graph visualizationsoftware. It has several main graph layout programs.It also has web and interactive graphical interfaces,and auxiliary tools, libraries, and language bindings.Microsoft Automatic Graph Layout 3 - formerlyknown as GLEE, is a .NET tool for laying out andvisualizing directed graphs. MSAGL can be used torepresent complex directed graphs as well as trees.MSAGL includes three integrated components: (i) Anautomatic layout engine is used to position and connectgraphs’ vertices. (ii) A drawing layer enables themodification of the attributes (e.g. color, style) of thegraphical components. (iii) A Windows-based viewerthat uses the engine and drawing layer to create interactivegraphs.Both products are technology specific and far toocomplex for our task.2 www.graphviz.org3 www.research.microsoft.comFigure 1: Position of a node3 DRAWING <strong>ALGORITHM</strong>When building a BST the coordinates of every nodedepend on the node’s relative position to other nodesin a tree. In other words, the knowledge of a tree’sstructure is required. In particular, the number of anode’s children, siblings, ancestors and descendantsand their position influence the position of a currentlyconsidered node. On the Figure 1 the nodes 85 and83 have different horizontal coordinates depending onthe number of children and siblings respectively.The BST data structure does not offer this informationand the only way to get it is to traverse a treeor at least some part of it. Of course, before drawinga node we could pre-process the required part ofthe tree, but this would ensue a performance hit anddrawing a large tree would become slow.In this section we present two approaches of drawinga BST. Each of them draws a tree in θ(N) time,where N is the number of nodes in a tree. Memoryconsumption depends linearly on the height of a tree- O(h) 4 . Both algorithms draw a BST while they traverseit. No node is visited twice. Both algorithmsrequire the height of a tree to be known and the secondalgorithms needs the number of nodes in a tree.The algorithms below assume that a BST is presentedas a number of interlinked instances of a Nodestructure. The structure has the following elements:(i) Key - an integer denoting the key of a node; (ii)4 For a randomly built tree the height is limited by log 2 n


Figure 2: Logical gridFigure 3: Cell indicesRl - a right child, a link/pointer to another instanceof Node structure; (iii) Ll - a left child, a link/pointerto another instance of Node structure. If a node doesnot have any of the children a corresponding pointeris set to null. In addition no tree contains duplicatednodes 5 .3.1 Drawing BST with FixedCoordinatesThe algorithm presented in this subsection calculatesthe coordinates of a node from the node’s depth andthe position of the node at its level. The Figure 2 helpsto understand how the algorithm works. The figureshows a logical grid in the cells of which the nodesof a BST are drawn. All cells of the logical grid areindexed as on the Figure 3.Using the following rules the algorithm defines acell in which a node must be drawn: (i) The root isalways drawn in the cell (0,0); (ii) The row index iof any child equals to that of its parent plus 1; (iii)The column index j of a left child equals to doubled5 This is not a critical assumption and does not changethe algorithms. This assumption simplifies drawing linesconnecting nodes.column index of its parent, and for the right child jequals to the index of the left child plus 1.The algorithm traverses a tree in postorder. Therefore,children of any node are drawn first. Every levelof the tree gets equal space on a canvas. This spaceis divided into equal compartments and in the middleof each compartment a node is drawn. The number ofcompartments equals the maximum number of nodesat a given level - 2 i , where i is the vertical distancefrom a node to the root of the tree, called the depth ofa node. The depth of the root is 0.The algorithm requires a canvas of the sizeCanvas width = wc ∗ 2 TreeHeightCanvas height = hc ∗ TreeHeight(1)where wc,hc are the width and height of a compartmentat the bottom level of the grid. These are constantsdefined by a programmer. The width of compartmentsat other levels is W i = wc ∗ 2 TreeHeight−i asshown on the Figure 2.The following listing demonstrates the algorithmimplemented in C#.void DisplayTree(Node root) {if (root == null)return;//Start the recursion from//the root’s childrenif (root.Ll != null)DrawTree(root.Ll, root, 0, 0);if (root.Rl != null)DrawTree(root.Rl, root, 0, 0);//Calculate the root’s X-coordinateint x = wc*Math.Pow(2,H-1);Ellipse(x-d/2, (hc-d)/2, d, d);DrawString(root.ToString(),x-d/2, hc/2-d/3);}//c - a node to draw//p - the parent of the c-node//i,j - indices of the parent’s cellvoid DrawTree(Node c, Node p,int i, int j) {//Indices of the c-node’s cellint ic, jc;ic = i + 1;jc = 2 * j;if (p.Key < c.Key)//c-node is the right childjc++;if (c.Ll != null)DrawTree(c.Ll, c, ic, jc);if (c.Rl != null)


}//The width of a subtreeint stW = 0;//X-coordinate of a subtree’s rootint stRX;if (c.IsLeaf) {w = d;rX = oX;}else {//Draw left subtreeif (c.Ll != null) {DrawTree(c.Ll, oX, oY+hc,out stRX, out stW);w = stW;//Draw a line connecting the left//subtree with the c-noderX = oX+stW-d/2;Line(rX+d/2,oY+d,stRX+d/2,oY+hc);}else {//Handling the case if there is//no left childw = d/2;rX = oX;}//Draw right subtreeif (c.Rl != null) {DrawTree(c.Rl, oX+w, oY+hc,out stRX, out stW);w += stW;//Draw a line connecting the right//subtree with the c-nodeLine(rX+d/2,oY+d,stRX+d/2,oY+hc);}else//Handling the case if there is//no right childw += d/2;}//Draw the c-nodeDrawString(c.ToString(), rX, oY);Ellipse(rX, oY, d, d);The Figure 6 shows how the same tree from the previoussubsection is drawn in a more compact way.The algorithm requires a canvas of the sizewc ∗ (N + 1)Canvas width

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!