Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/386.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 二叉树中的节点交叉_Java_Swing_Tree_Binary Tree - Fatal编程技术网

Java 二叉树中的节点交叉

Java 二叉树中的节点交叉,java,swing,tree,binary-tree,Java,Swing,Tree,Binary Tree,我正在编写代码来构建一棵二叉树,并将其显示给家庭作业。(因此,很自然,我必须从头开始构建这棵树。)代码起作用,但我似乎无法找到一种方法来防止节点在树下跨越大约4层。我希望有人能帮我开动脑筋。。。但是,有没有办法检查树向下有多少层,并调整上面层节点之间的水平距离?在我的研究中,我看到了一些不同的方法,但我的方法是递归地使用displayTree()方法,根据赋值参数。感谢您的帮助 另外,当前的horizontalGap变量是我一直在修补的,所以如果它弄乱了代码,我道歉。下面是displayTree

我正在编写代码来构建一棵二叉树,并将其显示给家庭作业。(因此,很自然,我必须从头开始构建这棵树。)代码起作用,但我似乎无法找到一种方法来防止节点在树下跨越大约4层。我希望有人能帮我开动脑筋。。。但是,有没有办法检查树向下有多少层,并调整上面层节点之间的水平距离?在我的研究中,我看到了一些不同的方法,但我的方法是递归地使用displayTree()方法,根据赋值参数。感谢您的帮助

另外,当前的horizontalGap变量是我一直在修补的,所以如果它弄乱了代码,我道歉。下面是displayTree()方法


这是交叉节点问题的一个示例

我认为节点开始在某个层次交叉的事实是如何显示树的结果。较低级别的节点数可能比较高级别的节点数高得多,因此需要在节点数最多的级别确定最小空间量。这会导致在更高级别上出现大量空白

您希望支持多少级别?您可以计算某个级别上最大数量节点的最小空间(例如,根节点下6个级别的2^6=64个节点的10个像素),并将每个更高级别的空间加倍

您还可以使用不同的方式来显示树,如“文件管理器”式方法,其中子节点占用的空间与它们所需的空间相同:

编辑:代码示例

如果您想从堆栈溢出中快速获得好的答案,最好在问题中添加一个简短、可运行的问题示例(所谓的最小、完整且可验证的示例:请参阅以获取更多信息)。这样你就可以帮助别人来帮助你

这是我添加到您的代码中的一些代码,用于创建具有可能解决方案的示例:

// Main class TreeFromScratch:

import java.awt.BorderLayout;
import javax.swing.*;

public class TreeFromScratch {
    public static void main(final String[] arguments) {
        SwingUtilities.invokeLater(() -> new TreeFromScratch().createAndShowGui());
    }

    private void createAndShowGui() {
        final JFrame frame = new JFrame("Stack Overflow");
        frame.setBounds(100, 100, 1200, 600);
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

        final JPanel panel = new JPanel(new BorderLayout());
        final Node tree = createTree();
        panel.add(new CustomTree(tree), BorderLayout.CENTER);
        frame.getContentPane().add(panel);

        frame.setVisible(true);
    }

    private Node createTree() {
        final Node tree = new Node('a');
        tree.leftChild = new Node('b');

        tree.leftChild.leftChild = new Node('c');
        tree.leftChild.leftChild.leftChild = new Node('d');
        tree.leftChild.leftChild.leftChild.leftChild = new Node('e');
        tree.leftChild.leftChild.leftChild.leftChild.leftChild = new Node('f');

        tree.leftChild.rightChild = new Node('g');
        tree.leftChild.rightChild.rightChild = new Node('h');
        tree.leftChild.rightChild.rightChild.rightChild = new Node('i');
        tree.leftChild.rightChild.rightChild.rightChild.rightChild = new Node('j');

        tree.rightChild = new Node('k');
        tree.rightChild.leftChild = new Node('l');
        tree.rightChild.leftChild.leftChild = new Node('m');
        tree.rightChild.leftChild.leftChild.leftChild = new Node('n');
        tree.rightChild.leftChild.leftChild.leftChild.leftChild = new Node('o');

        return tree;
    }
}


// Class CustomTree:

import java.awt.Graphics;
import javax.swing.JPanel;

public class CustomTree extends JPanel {
    private Node tree;
    private int radius = 40;

    public CustomTree(Node tree) {
        this.tree = tree;
    }

    @Override
    protected void paintComponent(Graphics g) {
        displayTree(g, tree, 660, 100, 1);
    }

    //displayTree() with crossing issue
    //**************************************************************************
    public void displayTree(Graphics g, Node localTree, int x, int y, int level) {
        // Display the root
        int verticalGap = 50;
        //int horizontalGap = 250 / level;
        int horizontalGap = (int) (660 / Math.pow(2, level));

        g.drawOval(x, y, radius, radius);
        g.drawString(localTree.getKey() + "", x + (radius / 4), y + 20);

        if (localTree.getLeft() != null) {
            // Draw a line to the left node
            lineToLeftChild(g, x - horizontalGap, y + verticalGap, x, y);
            // Draw the left subtree recursively
            displayTree(g, localTree.leftChild, x - horizontalGap, y + verticalGap,
                        level + 1);
        }

        if (localTree.rightChild != null) {
            // Draw a line to the right node
            lineToRightChild(g, x + horizontalGap, y + verticalGap, x, y);
            // Draw the right subtree recursively
            displayTree(g, localTree.rightChild, x + horizontalGap, y + verticalGap,
                        level + 1);
        }
    }//end displayTree()
    //**************************************************************************

    //Line to child
    //**************************************************************************
    private void lineToLeftChild(Graphics g, int x1, int y1, int x2, int y2) {
        g.drawLine(x1 + (radius / 2), y1, x2, y2 + (radius / 2));
    }//end LinetoLeft
    //**************************************************************************

    //Line to child
    //**************************************************************************
    private void lineToRightChild(Graphics g, int x1, int y1, int x2, int y2) {
        g.drawLine(x1 + (radius / 2), y1, (x2 + radius), y2 + (radius / 2));
    }//end line to Right()
    //**************************************************************************
}


// Class Node:

public class Node {
    private char key;
    protected Node leftChild;
    protected Node rightChild;

    public Node(char key) {
        this.key = key;
    }

    public char getKey() {
        return key;
    }

    public Node getLeft() {
        return leftChild;
    }
}
使用不同的方法计算水平间隙,树现在看起来如下所示:

// Main class TreeFromScratch:

import java.awt.BorderLayout;
import javax.swing.*;

public class TreeFromScratch {
    public static void main(final String[] arguments) {
        SwingUtilities.invokeLater(() -> new TreeFromScratch().createAndShowGui());
    }

    private void createAndShowGui() {
        final JFrame frame = new JFrame("Stack Overflow");
        frame.setBounds(100, 100, 1200, 600);
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

        final JPanel panel = new JPanel(new BorderLayout());
        final Node tree = createTree();
        panel.add(new CustomTree(tree), BorderLayout.CENTER);
        frame.getContentPane().add(panel);

        frame.setVisible(true);
    }

    private Node createTree() {
        final Node tree = new Node('a');
        tree.leftChild = new Node('b');

        tree.leftChild.leftChild = new Node('c');
        tree.leftChild.leftChild.leftChild = new Node('d');
        tree.leftChild.leftChild.leftChild.leftChild = new Node('e');
        tree.leftChild.leftChild.leftChild.leftChild.leftChild = new Node('f');

        tree.leftChild.rightChild = new Node('g');
        tree.leftChild.rightChild.rightChild = new Node('h');
        tree.leftChild.rightChild.rightChild.rightChild = new Node('i');
        tree.leftChild.rightChild.rightChild.rightChild.rightChild = new Node('j');

        tree.rightChild = new Node('k');
        tree.rightChild.leftChild = new Node('l');
        tree.rightChild.leftChild.leftChild = new Node('m');
        tree.rightChild.leftChild.leftChild.leftChild = new Node('n');
        tree.rightChild.leftChild.leftChild.leftChild.leftChild = new Node('o');

        return tree;
    }
}


// Class CustomTree:

import java.awt.Graphics;
import javax.swing.JPanel;

public class CustomTree extends JPanel {
    private Node tree;
    private int radius = 40;

    public CustomTree(Node tree) {
        this.tree = tree;
    }

    @Override
    protected void paintComponent(Graphics g) {
        displayTree(g, tree, 660, 100, 1);
    }

    //displayTree() with crossing issue
    //**************************************************************************
    public void displayTree(Graphics g, Node localTree, int x, int y, int level) {
        // Display the root
        int verticalGap = 50;
        //int horizontalGap = 250 / level;
        int horizontalGap = (int) (660 / Math.pow(2, level));

        g.drawOval(x, y, radius, radius);
        g.drawString(localTree.getKey() + "", x + (radius / 4), y + 20);

        if (localTree.getLeft() != null) {
            // Draw a line to the left node
            lineToLeftChild(g, x - horizontalGap, y + verticalGap, x, y);
            // Draw the left subtree recursively
            displayTree(g, localTree.leftChild, x - horizontalGap, y + verticalGap,
                        level + 1);
        }

        if (localTree.rightChild != null) {
            // Draw a line to the right node
            lineToRightChild(g, x + horizontalGap, y + verticalGap, x, y);
            // Draw the right subtree recursively
            displayTree(g, localTree.rightChild, x + horizontalGap, y + verticalGap,
                        level + 1);
        }
    }//end displayTree()
    //**************************************************************************

    //Line to child
    //**************************************************************************
    private void lineToLeftChild(Graphics g, int x1, int y1, int x2, int y2) {
        g.drawLine(x1 + (radius / 2), y1, x2, y2 + (radius / 2));
    }//end LinetoLeft
    //**************************************************************************

    //Line to child
    //**************************************************************************
    private void lineToRightChild(Graphics g, int x1, int y1, int x2, int y2) {
        g.drawLine(x1 + (radius / 2), y1, (x2 + radius), y2 + (radius / 2));
    }//end line to Right()
    //**************************************************************************
}


// Class Node:

public class Node {
    private char key;
    protected Node leftChild;
    protected Node rightChild;

    public Node(char key) {
        this.key = key;
    }

    public char getKey() {
        return key;
    }

    public Node getLeft() {
        return leftChild;
    }
}