目录
前言
插入
删除
查询
1.树节点类
class TreeNode {
private String value;
private TreeNode left;
private TreeNode right;
public TreeNode(String value) {
this.value = value;
this.left = null;
this.right = null;
}
public String getValue() {
return value;
}
public TreeNode getLeft() {
return left;
}
public TreeNode getRight() {
return right;
}
public void setLeft(TreeNode left) {
this.left = left;
}
public void setRight(TreeNode right) {
this.right = right;
}
public void setValue(String value) {
this.value = value;
}
}
定义了一个树节点类(TreeNode),包含节点的值(value)、左子节点(left)和右子节点(right)。设置和得到其节点的值
2.二叉树类
2.1插入
public void insert(String value) {
// 如果根节点为空,则创建一个新的树节点
if (root == null) {
root = new TreeNode(value);
} else {
// 否则,插入新节点
insertNode(root, value);
}
}
// 递归插入节点
private void insertNode(TreeNode node, String value) {
//比较当前节点的值和插入的值的大小
if (value.compareTo(node.getValue()) < 0) {
//如果当前节点的左子节点为空,则插入新节点
if (node.getLeft() == null) {
node.setLeft(new TreeNode(value));
} else {
//如果当前节点的左子节点不为空,则递归插入新节点
insertNode(node.getLeft(), value);
}
} else {
//如果当前节点的右子节点为空,则插入新节点
if (node.getRight() == null) {
node.setRight(new TreeNode(value));
} else {
//如果当前节点的右子节点不为空,则递归插入新节点
insertNode(node.getRight(), value);
}
}
}
递归插入,先比较和其根节点的大小,若小于,插入其左子树;若大于插入其右子树;记得判断是不是空的,若是空的插入下一个左子树或右子树。
2.2删除
public void delete(String value) {
// 删除值为value的节点,并将删除后的节点赋值给root
root = deleteNode(root, value);
}
// 递归删除节点
private TreeNode deleteNode(TreeNode node, String value) {
// 如果节点为空,则返回空
if (node == null) {
return null;
}
// 如果要删除的值小于当前节点的值,则递归删除左子树
if (value.compareTo(node.getValue()) < 0) {
node.setLeft(deleteNode(node.getLeft(), value));
// 如果要删除的值大于当前节点的值,则递归删除右子树
} else if (value.compareTo(node.getValue()) > 0) {
node.setRight(deleteNode(node.getRight(), value));
// 如果要删除的值等于当前节点的值,则分情况处理
} else {
// 如果当前节点没有左右子树,则返回空
if (node.getLeft() == null && node.getRight() == null) {
return null;
// 如果当前节点只有左子树,则返回左子树
} else if (node.getLeft() == null) {
return node.getRight();
// 如果当前节点只有右子树,则返回右子树
} else if (node.getRight() == null) {
return node.getLeft();
// 如果当前节点左右子树都存在,则找到右子树的最小节点,将当前节点的值替换为该最小节点的值,然后递归删除该最小节点
} else {
TreeNode minNode = findMinNode(node.getRight());
node.setValue(minNode.getValue());
node.setRight(deleteNode(node.getRight(), minNode.getValue()));
}
}
return node;
}
// 查找最小节点
private TreeNode findMinNode(TreeNode node) {
// 循环查找左子树的最小节点
while (node.getLeft() != null) {
node = node.getLeft();
}
return node;
}
比较删除的值和当前节点的大小,若小于则递归删除左子树,大于则递归删除右子树,等于分为四种情况,当前节点没有左子树和右子树,就删他,只有左子树,则删左子树,只有右子树,则删右子树,两个树都有, 则找到右子树的最小节点,将当前节点值替换成最小节点值,然后递归删除该最小节点。
2.3查询
// 查找节点
public boolean search(String value) {
// 调用searchNode函数,传入根节点和要搜索的值,返回搜索结果
return searchNode(root, value);
}
// 递归查找节点
private boolean searchNode(TreeNode node, String value) {
// 如果节点为空,返回false
if (node == null) {
return false;
}
// 如果节点值等于value,返回true
if (value.equals(node.getValue())) {
return true;
// 如果节点值小于value,在左子树中查找
} else if (value.compareTo(node.getValue()) < 0) {
return searchNode(node.getLeft(), value);
// 如果节点值大于value,在右子树中查找
} else {
return searchNode(node.getRight(), value);
}
}
比较节点值和根节点的大小,等于返回TURE,小于在左子树查找,大于在右子树查找,递归出口为节点为空,返回FLASE
3.二叉树可视化
public class BinaryTreeVisualization extends JFrame {
private BinaryTree binaryTree;
private DefaultTreeModel treeModel;
private JTextField valueField;
private JTextArea resultArea;
public BinaryTreeVisualization() {
// 创建一个BinaryTree对象
binaryTree = new BinaryTree();
// 创建一个DefaultTreeModel对象,并传入null
treeModel = new DefaultTreeModel(null);
// 初始化二叉树
binaryTree.insert("5");
binaryTree.insert("3");
binaryTree.insert("7");
binaryTree.insert("2");
binaryTree.insert("4");
binaryTree.insert("6");
binaryTree.insert("8");
// 创建一个JTree,将treeModel作为参数传入
JTree tree = new JTree(treeModel);
// 创建一个JScrollPane,将tree作为参数传入
JScrollPane treeScrollPane = new JScrollPane(tree);
// 设置treeScrollPane的尺寸为(400,400)
treeScrollPane.setPreferredSize(new Dimension(400, 400));
// 创建一个JTextField,宽度为10
valueField = new JTextField(10);
JButton insertButton = new JButton("插入");
insertButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
//获取输入框中的值
String value = valueField.getText();
//将值插入到二叉树中
binaryTree.insert(value);
//更新二叉树
updateTree();
//清空输入框
valueField.setText("");
//输出插入成功
resultArea.setText("插入成功");
}
});
JButton deleteButton = new JButton("删除");
deleteButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
//获取输入框中的值
String value = valueField.getText();
//将值从二叉树中删除
binaryTree.delete(value);
//更新二叉树
updateTree();
//清空输入框
valueField.setText("");
//输出删除成功
resultArea.setText("删除成功");
}
});
JButton searchButton = new JButton("查询");
searchButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
//获取输入框中的值
String value = valueField.getText();
//查询二叉树中是否有这个值
boolean found = binaryTree.search(value);
if (found) {
//输出查询成功,有这个节点
resultArea.setText("查询成功,有这个节点");
} else {
//输出查询失败,没有这个节点
resultArea.setText("查询失败,没有这个节点");
}
//清空输入框
valueField.setText("");
}
});
resultArea = new JTextArea(5, 20);
resultArea.setEditable(false);
JPanel controlPanel = new JPanel();
controlPanel.add(new JLabel("节点值:"));
controlPanel.add(valueField);
controlPanel.add(insertButton);
controlPanel.add(deleteButton);
controlPanel.add(searchButton);
Container contentPane = getContentPane();
contentPane.setLayout(new BorderLayout());
contentPane.add(treeScrollPane, BorderLayout.CENTER);
contentPane.add(controlPanel, BorderLayout.NORTH);
contentPane.add(resultArea, BorderLayout.SOUTH);
//设置窗口的关闭操作
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//设置窗口的标题
setTitle("二叉树可视化");
//设置窗口的尺寸
pack();
//设置窗口的位置
setLocationRelativeTo(null);
//设置窗口的可见性
setVisible(true);
//更新二叉树
updateTree();
}
// 更新树的显示
private void updateTree() {
//创建根节点
DefaultMutableTreeNode root = createTreeNode(binaryTree.getRoot());
//设置根节点
treeModel.setRoot(root);
//重新加载树模型
treeModel.reload();
}
// 创建树节点
private DefaultMutableTreeNode createTreeNode(TreeNode node) {
// 创建一个DefaultMutableTreeNode对象,并传入node的值
DefaultMutableTreeNode treeNode = new DefaultMutableTreeNode(node.getValue());
// 如果node的左子树不为空,则添加到treeNode中
if (node.getLeft() != null) {
treeNode.add(createTreeNode(node.getLeft()));
}
// 如果node的右子树不为空,则添加到treeNode中
if (node.getRight() != null) {
treeNode.add(createTreeNode(node.getRight()));
}
// 返回treeNode
return treeNode;
}
public static void main(String[] args) {
// 使用SwingUtilities的invokeLater方法,在UI线程中运行BinaryTreeVisualization类
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new BinaryTreeVisualization();
}
});
}
}
2.1界面设计
有插入,查询和删除按钮,然后展示二叉树的结构。
DefaultMutableTreeNode
是javax.swing.tree
包中的一个类,它表示一棵默认的树形结构。这个类提供了基本的树节点操作,例如添加子节点、删除子节点、设置和获取节点的值等。可以加载树的结构
4.总代码
import javax.swing.*;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
// 树节点类
class TreeNode {
private String value;
private TreeNode left;
private TreeNode right;
public TreeNode(String value) {
this.value = value;
this.left = null;
this.right = null;
}
public String getValue() {
return value;
}
public TreeNode getLeft() {
return left;
}
public TreeNode getRight() {
return right;
}
public void setLeft(TreeNode left) {
this.left = left;
}
public void setRight(TreeNode right) {
this.right = right;
}
public void setValue(String value) {
this.value = value;
}
}
// 二叉树类
class BinaryTree {
private TreeNode root;
public BinaryTree() {
root = null;
}
public TreeNode getRoot() {
return root;
}
// 插入节点
public void insert(String value) {
// 如果根节点为空,则创建一个新的树节点
if (root == null) {
root = new TreeNode(value);
} else {
// 否则,插入新节点
insertNode(root, value);
}
}
// 递归插入节点
private void insertNode(TreeNode node, String value) {
//比较当前节点的值和插入的值的大小
if (value.compareTo(node.getValue()) < 0) {
//如果当前节点的左子节点为空,则插入新节点
if (node.getLeft() == null) {
node.setLeft(new TreeNode(value));
} else {
//如果当前节点的左子节点不为空,则递归插入新节点
insertNode(node.getLeft(), value);
}
} else {
//如果当前节点的右子节点为空,则插入新节点
if (node.getRight() == null) {
node.setRight(new TreeNode(value));
} else {
//如果当前节点的右子节点不为空,则递归插入新节点
insertNode(node.getRight(), value);
}
}
}
// 删除节点
public void delete(String value) {
// 删除值为value的节点,并将删除后的节点赋值给root
root = deleteNode(root, value);
}
// 递归删除节点
private TreeNode deleteNode(TreeNode node, String value) {
// 如果节点为空,则返回空
if (node == null) {
return null;
}
// 如果要删除的值小于当前节点的值,则递归删除左子树
if (value.compareTo(node.getValue()) < 0) {
node.setLeft(deleteNode(node.getLeft(), value));
// 如果要删除的值大于当前节点的值,则递归删除右子树
} else if (value.compareTo(node.getValue()) > 0) {
node.setRight(deleteNode(node.getRight(), value));
// 如果要删除的值等于当前节点的值,则分情况处理
} else {
// 如果当前节点没有左右子树,则返回空
if (node.getLeft() == null && node.getRight() == null) {
return null;
// 如果当前节点只有左子树,则返回左子树
} else if (node.getLeft() == null) {
return node.getRight();
// 如果当前节点只有右子树,则返回右子树
} else if (node.getRight() == null) {
return node.getLeft();
// 如果当前节点左右子树都存在,则找到右子树的最小节点,将当前节点的值替换为该最小节点的值,然后递归删除该最小节点
} else {
TreeNode minNode = findMinNode(node.getRight());
node.setValue(minNode.getValue());
node.setRight(deleteNode(node.getRight(), minNode.getValue()));
}
}
return node;
}
// 查找最小节点
private TreeNode findMinNode(TreeNode node) {
// 循环查找左子树的最小节点
while (node.getLeft() != null) {
node = node.getLeft();
}
return node;
}
// 查找节点
public boolean search(String value) {
// 调用searchNode函数,传入根节点和要搜索的值,返回搜索结果
return searchNode(root, value);
}
// 递归查找节点
private boolean searchNode(TreeNode node, String value) {
// 如果节点为空,返回false
if (node == null) {
return false;
}
// 如果节点值等于value,返回true
if (value.equals(node.getValue())) {
return true;
// 如果节点值小于value,在左子树中查找
} else if (value.compareTo(node.getValue()) < 0) {
return searchNode(node.getLeft(), value);
// 如果节点值大于value,在右子树中查找
} else {
return searchNode(node.getRight(), value);
}
}
}
// 二叉树可视化界面类
public class BinaryTreeVisualization extends JFrame {
private BinaryTree binaryTree;
private DefaultTreeModel treeModel;
private JTextField valueField;
private JTextArea resultArea;
public BinaryTreeVisualization() {
// 创建一个BinaryTree对象
binaryTree = new BinaryTree();
// 创建一个DefaultTreeModel对象,并传入null
treeModel = new DefaultTreeModel(null);
// 初始化二叉树
binaryTree.insert("5");
binaryTree.insert("3");
binaryTree.insert("7");
binaryTree.insert("2");
binaryTree.insert("4");
binaryTree.insert("6");
binaryTree.insert("8");
// 创建一个JTree,将treeModel作为参数传入
JTree tree = new JTree(treeModel);
// 创建一个JScrollPane,将tree作为参数传入
JScrollPane treeScrollPane = new JScrollPane(tree);
// 设置treeScrollPane的尺寸为(400,400)
treeScrollPane.setPreferredSize(new Dimension(400, 400));
// 创建一个JTextField,宽度为10
valueField = new JTextField(10);
JButton insertButton = new JButton("插入");
insertButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
//获取输入框中的值
String value = valueField.getText();
//将值插入到二叉树中
binaryTree.insert(value);
//更新二叉树
updateTree();
//清空输入框
valueField.setText("");
//输出插入成功
resultArea.setText("插入成功");
}
});
JButton deleteButton = new JButton("删除");
deleteButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
//获取输入框中的值
String value = valueField.getText();
//将值从二叉树中删除
binaryTree.delete(value);
//更新二叉树
updateTree();
//清空输入框
valueField.setText("");
//输出删除成功
resultArea.setText("删除成功");
}
});
JButton searchButton = new JButton("查询");
searchButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
//获取输入框中的值
String value = valueField.getText();
//查询二叉树中是否有这个值
boolean found = binaryTree.search(value);
if (found) {
//输出查询成功,有这个节点
resultArea.setText("查询成功,有这个节点");
} else {
//输出查询失败,没有这个节点
resultArea.setText("查询失败,没有这个节点");
}
//清空输入框
valueField.setText("");
}
});
resultArea = new JTextArea(5, 20);
resultArea.setEditable(false);
JPanel controlPanel = new JPanel();
controlPanel.add(new JLabel("节点值:"));
controlPanel.add(valueField);
controlPanel.add(insertButton);
controlPanel.add(deleteButton);
controlPanel.add(searchButton);
Container contentPane = getContentPane();
contentPane.setLayout(new BorderLayout());
contentPane.add(treeScrollPane, BorderLayout.CENTER);
contentPane.add(controlPanel, BorderLayout.NORTH);
contentPane.add(resultArea, BorderLayout.SOUTH);
//设置窗口的关闭操作
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//设置窗口的标题
setTitle("二叉树可视化");
//设置窗口的尺寸
pack();
//设置窗口的位置
setLocationRelativeTo(null);
//设置窗口的可见性
setVisible(true);
//更新二叉树
updateTree();
}
// 更新树的显示
private void updateTree() {
//创建根节点
DefaultMutableTreeNode root = createTreeNode(binaryTree.getRoot());
//设置根节点
treeModel.setRoot(root);
//重新加载树模型
treeModel.reload();
}
// 创建树节点
private DefaultMutableTreeNode createTreeNode(TreeNode node) {
// 创建一个DefaultMutableTreeNode对象,并传入node的值
DefaultMutableTreeNode treeNode = new DefaultMutableTreeNode(node.getValue());
// 如果node的左子树不为空,则添加到treeNode中
if (node.getLeft() != null) {
treeNode.add(createTreeNode(node.getLeft()));
}
// 如果node的右子树不为空,则添加到treeNode中
if (node.getRight() != null) {
treeNode.add(createTreeNode(node.getRight()));
}
// 返回treeNode
return treeNode;
}
public static void main(String[] args) {
// 使用SwingUtilities的invokeLater方法,在UI线程中运行BinaryTreeVisualization类
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new BinaryTreeVisualization();
}
});
}
}