set position for drawing binary tree

假装没事ソ 提交于 2019-12-09 07:13:24

问题


I want to drawing a binary tree with an graphical framework(Qt) like this:

        9
       /  \
      1    10
    /  \     \
   0    5     11
  /    /  \
 -1   2    6

but I have a problem to set X and Y for every node, do you any idea to setting and fixation position ? (I have only height of every node and left-Child and right-Child)


回答1:


Given the width canvasWidth and the height canvasHeight of the canvas you can calculate position of each node.

First, let's assign two numbers to each node: the depth of the node and a serial index of the node in fully filled row. In your example, for each node we assign (depth, index) as

          (0, 1)
         /      \
     (1, 1)      (1, 2)
     /   \            \
 (2, 1)  (2, 2)      (2, 4)
 /       /     \
(3, 1)  (3, 3) (3, 4)

As @j_random_hacker pointed, we can find the index of a node recursively using this equation:

leftChildIndex = parentIndex * 2 - 1
rightChildIndex = parentIndex * 2

This can be done using BFS (cost: O(n)). During this traversal let's save also information about the depth of the whole tree treeDepth. In our case treeDepth=3

Then given canvasWidth, canvasHeight and treeDepth as global constants, each node's position can be found like this:

def position(depth, index):
    x = index * canvasWidth / (2^depth + 1)
    y = depth * canvasHeight / treeDepth
    return y, x

So in your case positions will be (canvasHeight/treeDepth*y, canvasWidth*x) where (y,x) for every node

           (0, 1/2)
         /          \
     (1, 1/3)       (1, 2/3)
     /      \            \
 (2, 1/5)   (2, 2/5)      (2, 4/5)
 /           /     \
(3, 1/9) (3, 3/9)  (3, 4/9)

Cost: O(n)




回答2:


Improve the Pavel Zaichenkov's solution,

Let the root's index be 1, and for the other node:

leftNodeIndex = parentNodeIndex * 2 - 1
rightNodeIndex = parentNodeIndex * 2 + 1

And the Y would be (consider the depth start from 1):

Y = nodeIndex / (2 ^ depth)

This algorithm makes that if a node has two childs, then the distance between the node and left-child and the distance between the node and right-child woudl be equal:

Y - leftChlidY = rightChlidY - Y
           (1, 1/2)
         /          \
     (2, 1/4)       (2, 3/4)
     /      \            \
 (3, 1/8)   (3, 3/8)     (3, 7/8)
 /           /      \
(4, 1/16) (4, 5/16)  (4, 7/16)



回答3:


I've written an article about this very subject. It can be found here: http://adhavoc.com/BinaryTree.html

Essentially, you need to move every child node as left as it can possibly be placed, with the caveat that the child nodes must be left and right of the parent respectively. Then move left branches as far right as possible, with the same caveat.




回答4:


I write it in c++ using openframework(http://www.openframeworks.cc/) as a graphical interface.

////////////////////////
void BSTree:: paint()
{
ppx=ofGetWidth()/(2+numNode());
ppy=ofGetHeight()/(2+findHeight());
draw(root,1,1);
}
 ////////////////////////
 int BSTree:: draw(TreeNode *n,int x,int y)
 {
int xr=x;  
if(n==NULL) return xr 
int lx=draw(n->l,x,y+1); 
xr+=numNode2(n->l); 
int rx=draw(n->r,xr+1,y+1);
n->draw(xr*ppx,y*ppy);
if(n->l!=NULL) ofLine(xr*ppx,y*ppy,lx*ppx,(y+1)*ppy);
if(n->r!=NULL) ofLine(xr*ppx,y*ppy,rx*ppx,(y+1)*ppy);

return xr;

 }



 ///////////////////////
 void TreeNode::draw(int x,int y)
 {
ofSetColor(255,130,200);
float radius = 25 ;
ofFill();       // draw "filled shapes"
ofCircle(x,y,radius);

ofSetHexColor(0x000000);
char xx[100] ;
sprintf(xx,"%d",data);
ofDrawBitmapString(xx, x-5,y);

 }



回答5:


I was looking for a way to draw binary trees in Qt and I couldn't find an example, so I made a lib to draw binary trees, here it is https://github.com/rom1504/GenericBinaryTree

Your method seems right at first (that's what I did first) but If the last layer isn't full the width of the displayed tree will be too large.



来源:https://stackoverflow.com/questions/14184655/set-position-for-drawing-binary-tree

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!