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