我正在研究构建二叉树的代码并将其显示为作业作业。(所以,当然,我必须从头开始构建树。)代码函数,但我似乎无法想象一种方法可以防止节点在树下穿过大约4层。我希望有人可以帮我启动我的大脑...但有没有办法检查树下降了多少级别并调整上面级别节点之间的水平距离?在我的研究中,我看到一些不同的做法,但我必须使用displayTree()方法递归地按照赋值参数。任何帮助表示赞赏。
P.S。当前的horizontalGap变量是我一直在修改的,所以如果它与代码混淆,我道歉。这是displayTree()方法。
//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;
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()
//**************************************************************************
}
答案 0 :(得分:2)
这是您跨越节点的问题的示例吗?
我认为您的节点在某个级别开始交叉的事实是您显示树的方式的结果。较低级别的节点数量可以远高于较高级别的节点数量,因此需要在具有最大节点数量的级别确定最小空间量。这可能会导致更高级别的大量空白。
您想支持多少个级别?您可以计算特定级别的最大节点数量的最小空间(对于2 ^ 6 = 10个像素=根节点下6个级别的64个节点),并且每个更高级别的空间加倍。
您还可以使用其他方式显示您的树,例如"文件管理器"就像来自The Java Tutorials - How to Use Trees的方法一样,子节点占用了所需的空间:
编辑:代码示例
如果您希望从Stack Overflow获得良好而快速的答案,最好在您的问题中添加一个简短,可运行的问题示例(一个所谓的最小,完整和可验证的示例:请参阅{{3} } 欲获得更多信息)。这样你就可以帮助别人帮助你了。
这是我在代码中添加的一些代码,用于创建一个可能的解决方案示例:
// 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;
}
}
使用不同的方式计算horizontalGap
,树现在看起来像这样: