Java中描述二叉树遍历的图
在我的程序中,我使用一个名为“curNode”的变量来表示树根。每次我在文本字段中输入0或1时,curNode将变为curNode.left或curNode.right,然后新的当前节点将变为红色而不是黑色。但它只有在我输入了一些东西之后才能工作,在init中,树根没有红色。 这是我的TriesView.java:Java中描述二叉树遍历的图,java,graph,paintcomponent,tree-traversal,Java,Graph,Paintcomponent,Tree Traversal,在我的程序中,我使用一个名为“curNode”的变量来表示树根。每次我在文本字段中输入0或1时,curNode将变为curNode.left或curNode.right,然后新的当前节点将变为红色而不是黑色。但它只有在我输入了一些东西之后才能工作,在init中,树根没有红色。 这是我的TriesView.java: package tree; import java.awt.*; import java.awt.event.KeyAdapter; import java.awt.event.K
package tree;
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.Stack;
import javax.swing.*;
public class TriesView extends JPanel {
/**
*
*/
private static final long serialVersionUID = 1L;
private Huffman tree; // A binary tree to be displayed
private PaintTree paintTree;
private JTextField pathTxt;
public HuffmanNode curNode;
private Stack<String> txtStack = new Stack<String>();
/** Construct a view for a binary tree */
public TriesView(Huffman tree) {
this.tree = tree; // Set a binary tree to be displayed
curNode = tree.root;
paintTree = new PaintTree();
setUI();
}
/** Initialize UI for binary tree */
private void setUI() {
this.setLayout(new BorderLayout());
JScrollPane scrollPane = new JScrollPane(paintTree, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
add(scrollPane, BorderLayout.CENTER);
if(!tree.isEmpty()){
paintTree.setPreferredSize(new Dimension((int)Math.pow(2, (tree.getDepth() + 1)) * paintTree.radius, (tree.getDepth() + 1) * paintTree.vGap + paintTree.radius));
scrollPane.setPreferredSize(new Dimension((int)Math.pow(2, (tree.getDepth() + 1)) * paintTree.radius, (tree.getDepth() + 1) * paintTree.vGap + paintTree.radius));
}
JPanel panel = new JPanel();
pathTxt = new JTextField(10);
panel.add(new JLabel("Enter key path: "));
panel.add(pathTxt);
add(panel, BorderLayout.SOUTH);
pathTxt.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent evt) {
String txt = pathTxt.getText();
txtStack.push(txt);
}
public void keyReleased(KeyEvent evt) {
String txt = pathTxt.getText();
String oldTxt = pathTxt.getText();
if(!txtStack.isEmpty())
oldTxt = txtStack.pop();
if (txt.matches("^[01]*$") != true) {
pathTxt.setText(oldTxt);
JOptionPane.showMessageDialog(null, "Ký tự không hợp lệ");
return;
}
HuffmanNode temp = tree.root;
for(int i = 0; i < txt.length() && temp != null; i++){
if(txt.charAt(i) == '0'){
temp = temp.left;
}else if(txt.charAt(i) == '1'){
temp = temp.right;
}
}
if(temp == null){
JOptionPane.showMessageDialog(null, "Dãy không hợp lệ");
pathTxt.setText(oldTxt);
return;
}
curNode = temp;
scrollPane.repaint();
}
});
}
// Inner class PaintTree for displaying a tree on a panel
class PaintTree extends JPanel {
/**
*
*/
private static final long serialVersionUID = 1L;
private int radius = 20; // Tree node radius
private int vGap = 50; // Gap between two levels in a tree
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (tree != null) {
// Display tree recursively
// displayTree(g, tree.root, (int)Math.pow(2, tree.root.height - 1)*radius, 30, (int)Math.pow(2, tree.root.height-2)*radius);
displayTree(g, tree.root, getWidth()/2, 30, getWidth()/4);
}
}
/** Display a subtree rooted at position (x, y) */
private void displayTree(Graphics g, HuffmanNode root,
int x, int y, int hGap) {
// Display the root
if(root == null) return;
Graphics2D ga = (Graphics2D)g;
if(curNode == root){
ga.setPaint(Color.RED);
}else{
ga.setPaint(Color.BLACK);
}
ga.fillOval(x - radius, y - radius, 2 * radius, 2 * radius);
ga.setPaint(Color.BLACK);
ga.setColor(Color.WHITE);
ga.drawString(String.valueOf(root.frequency), x - 6, y + 4);
ga.setColor(Color.RED);
ga.drawString(String.valueOf(root.value), x - 6, y + 36);
ga.setColor(Color.BLACK);
if (root.left != null) {
// Draw a line to the left node
connectLeftChild(g, x - hGap, y + vGap, x, y);
ga.drawString("0", x - hGap/2 - 12, y + vGap/2);
displayTree(g, root.left, x - hGap, y + vGap, Math.max(hGap / 2, radius));
}
if (root.right != null) {
// Draw a line to the right node
connectRightChild(g, x + hGap, y + vGap, x, y);
ga.drawString("1", x + hGap/2 + 5, y + vGap/2);
// Draw the right subtree recursively
displayTree(g, root.right, x + hGap, y + vGap, Math.max(hGap / 2, radius));
}
}
public int getRadius(){
return this.radius;
}
public int getVGap(){
return this.vGap;
}
/** Connect a parent at (x2, y2) with
* its left child at (x1, y1) */
private void connectLeftChild(Graphics g,
int x1, int y1, int x2, int y2) {
double d = Math.sqrt(vGap * vGap + (x2 - x1) * (x2 - x1));
int x11 = (int)(x1 + radius * (x2 - x1) / d);
int y11 = (int)(y1 - radius * vGap / d);
int x21 = (int)(x2 - radius * (x2 - x1) / d);
int y21 = (int)(y2 + radius * vGap / d);
g.drawLine(x11, y11, x21, y21);
}
/** Connect a parent at (x2, y2) with
* its right child at (x1, y1) */
private void connectRightChild(Graphics g,
int x1, int y1, int x2, int y2) {
double d = Math.sqrt(vGap * vGap + (x2 - x1) * (x2 - x1));
int x11 = (int)(x1 - radius * (x1 - x2) / d);
int y11 = (int)(y1 - radius * vGap / d);
int x21 = (int)(x2 + radius * (x1 - x2) / d);
int y21 = (int)(y2 + radius * vGap / d);
g.drawLine(x11, y11, x21, y21);
}
}
}
包树;
导入java.awt.*;
导入java.awt.event.KeyAdapter;
导入java.awt.event.KeyEvent;
导入java.util.Stack;
导入javax.swing.*;
公共类TriesView扩展了JPanel{
/**
*
*/
私有静态最终长serialVersionUID=1L;
私有哈夫曼树;//要显示的二叉树
私人漆树漆树;
私有jtextfieldpathtxt;
公共赫夫曼节点;
私有堆栈txtStack=新堆栈();
/**构造二叉树的视图*/
公共特里斯维尤(哈夫曼树){
this.tree=tree;//设置要显示的二叉树
curNode=tree.root;
paintTree=新的paintTree();
setUI();
}
/**初始化二叉树的用户界面*/
私有void setUI(){
此.setLayout(新的BorderLayout());
JScrollPane scrollPane=新的JScrollPane(画树、ScrollPaneConstants.VERTICAL滚动条、ScrollPaneConstants.HORIZONTAL滚动条);
添加(滚动窗格,BorderLayout.CENTER);
如果(!tree.isEmpty()){
paintTree.setPreferredSize(新维度((int)Math.pow(2,(tree.getDepth()+1))*paintTree.radius,(tree.getDepth()+1)*paintTree.vGap+paintTree.radius);
scrollPane.setPreferredSize(新维度((int)Math.pow(2,(tree.getDepth()+1))*paintTree.radius,(tree.getDepth()+1)*paintTree.vGap+paintTree.radius);
}
JPanel面板=新的JPanel();
pathTxt=新的JTextField(10);
添加(新JLabel(“输入键路径”);
panel.add(pathTxt);
添加(面板,边界布局。南部);
addKeyListener(新的KeyAdapter(){
按下公共无效键(KeyEvent evt){
String txt=pathTxt.getText();
txtStack.push(txt);
}
公共无效密钥已释放(密钥事件evt){
String txt=pathTxt.getText();
字符串oldTxt=pathTxt.getText();
如果(!txtStack.isEmpty())
oldTxt=txtStack.pop();
如果(txt.matches(“^[01]*$”)=true){
setText(oldTxt);
showMessageDialog(null,“Kýtự Khong hợPLệ");
返回;
}
HuffmanNode temp=tree.root;
对于(int i=0;i