图形二进制搜索树 - 节点间距

时间:2011-03-03 22:15:14

标签: java swing graphics binary-tree

我很难计算二进制搜索树中节点之间的间距。我实现了GUI,我可以通过导入文本文件以及其他功能等手动创建树或创建树。

在二叉搜索树节点类中,我应该使用X和Y坐标的getter和setter方法。现在,我已经开始工作,但这是我在互联网上点缀的代码混搭。例如,请参阅this link

问题是,我想要使用此代码,因为

  1. 这不是我的,
  2. 它没有使用提供的getter和setter方法。
  3. 我被告知为了使间距合适:

    X坐标与在有序遍历过程中处理节点的订单号成比例。

    Y坐标与节点的深度有关。

    我有一个getHeight()方法,它起作用,我认为与获取深度相同。

    我希望有人可以帮助我或指出我正确的方向。

    更新

    对于Y坐标?

    int index = -1;
    BinaryTreeNode nodes[];
    int[] levels;
    
    public void build(BinaryTreeNode node, int level)
    {
        if (node != null)
        {
            build(node.getLeftNode(), level+1);
            index++;
            nodes[index] = node;
            levels[index] = level;
            build(node.getRightNode(), level+1);
        }
    }
    

2 个答案:

答案 0 :(得分:0)

对于Y坐标,遍历父节点并总结每个父节点的高度。对于每个父母,也要添加一些白色间距,即

int y = 0;
Parent parent = child.getParent();
while(parent != null) {
   y += 10; // spacing
   y += parent.getHeight();

   parent = parent.getParent(); // next iteration
}

然而,这不是一个非常实用的方法。相反,你应该为级别迭代级别 - 从顶级节点开始,然后是前两个孩子,然后是4个孙子,依此类推。例如:将顶部节点添加到列表中,遍历列表并为其所有子节点创建新列表,然后将新列表设置为旧列表,并在while循环中继续,直到列表为空。

现在对于x位置来说,它更棘手,因为一个漂亮的布局取决于该特定级别的节点数量。如果节点3总是二进制和平衡的,则每级的n个节点的功率为2。如果没有,您必须首先检查每个级别有多少节点。完成后,只需将屏幕宽度除以节点数,然后按顺序放置,随时添加到x坐标。

编辑: 我更喜欢这种方法:

class BinaryTreeNode {

    BinaryTreeNode left;
    BinaryTreeNode right;

    int x;
    int y;
}

public void position(BinaryTreeNode root, int nodeHeight, int nodeWidth, int screenWidth, int screenHeight) {

    List<BinaryTreeNode> nodes = new ArrayList<BinaryTreeNode>();

    nodes.add(root);

    int level = 0;
    while(!nodes.isEmpty()) {

        // we know now the number of nodes and the level
        int y = level * nodeHeight;

        // the x position depends on the number of nodes:
        int widthPerNode = screenWidth / nodes.size();

        int x = 0; // start at leftmost

        // now have (fixed) y position and starting point for x (leftmost)
        for(BinaryTreeNode node : nodes) { // for loop iterates in-order
            node.y = y;
            node.x = x; // TODO: center node within available space

            x += widthPerNode;
        }

        // this level is complete, store all children in a list
        List<BinaryTreeNode> childNodes = new ArrayList<BinaryTreeNode>();
        for(BinaryTreeNode node : nodes) { // for loop iterates in-order
            if(node.left != null) {
                childNodes.add(node.left);
            }
            if(node.right != null) {
                childNodes.add(node.right);
            }
        }

        // continue to next level using the collected children as the new parents
        nodes = childNodes;

        level++;
    }

    // TODO: insert insets between nodes
    // TODO: insert stop criteria for y outside screen
    // TODO: insert stop criteria for x outside screen
    // TODO: getters and setters

}

此外,您可以修改此方法以返回需要绘制的节点(如果这不存在于paint()方法中)。

答案 1 :(得分:0)

Y轴很容易。将水平分散100像素,你就完成了。

X轴比较棘手。

假设您有1个节点(叶节点)。需要说40像素(因为圆的大小是40像素)

假设您有一个带有两个叶子节点的节点。总宽度= 40 * 2 + SPACING。 (比如SPACING = 20)= 100。

假设您有一个第三级节点。每个孩子都是100像素,所以100 * 2 + SPACING = 220。

第4级节点:220 * 2 + 20 = 460。

n级节点:40 * 2 ^(n-1)+(2 ^(n-1)-1)* 20 = SIZE * 2 ^(n-1)+ SPACING *(2 ^(n- 1) - 1)