设置绘制二叉树的位置

时间:2013-01-06 17:18:44

标签: algorithm tree drawing binary-tree drawing2d

我想用这样的图形框架(Qt)绘制二叉树:

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

但是我为每个节点设置X和Y都有问题,你知道设置和固定位置吗? (我只有每个节点的高度和左 - 儿童和右儿童)

5 个答案:

答案 0 :(得分:7)

给定画布的宽度canvasWidth和高度canvasHeight,您可以计算每个节点的位置。

首先,让我们为每个节点分配两个数字:节点的深度和完全填充行中节点的串行索引。在您的示例中,对于每个节点,我们将(depth, index)指定为

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

正如@j_random_hacker指出的那样,我们可以使用这个等式递归地找到一个节点的索引:

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

这可以使用BFS(成本:O(n))来完成。在此遍历过程中,我们还会保存有关整个树treeDepth深度的信息。在我们的案例中treeDepth=3

然后将canvasWidthcanvasHeighttreeDepth作为全局常量,可以像这样找到每个节点的位置:

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

因此,在您的情况下,每个节点的位置(canvasHeight/treeDepth*y, canvasWidth*x)(y,x)

           (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)

费用:O(n)

答案 1 :(得分:2)

改善Pavel Zaichenkov的解决方案,

让root的index为1,其他节点为:

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

Y将是(考虑深度从1开始):

Y = nodeIndex / (2 ^ depth)

该算法使得如果节点有两个子节点,那么节点和左子节点之间的距离以及节点和右子节点之间的距离应该相等:

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)

答案 2 :(得分:1)

我写了一篇关于这个主题的文章。可在此处找到:http://adhavoc.com/BinaryTree.html

基本上,您需要将每个子节点移动到可能放置的左侧,并注意子节点必须分别位于父节点的左侧和右侧。然后尽可能向右移动左侧分支,同样需要注意。

答案 3 :(得分:0)

我使用openframework(http://www.openframeworks.cc/)作为图形界面用c ++编写。

////////////////////////
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);

 }

答案 4 :(得分:0)

我一直在寻找一种在Qt中绘制二进制树的方法,我找不到一个例子,所以我创建了一个lib来绘制二叉树,这里是https://github.com/rom1504/GenericBinaryTree

你的方法一开始似乎是正确的(这是我先做的)但是如果最后一层没有填满,显示的树的宽度会太大。