import javax.swing.*;
import java.awt.*;
import java.util.Arrays;
public class SelectionSortVisualization extends JPanel {
public static final int WIDTH = 1000; // 界面宽度
public static final int HEIGHT = 600; // 界面高度
public static final int BAR_WIDTH = 50; // 柱体宽度
public static final int BAR_SPACING = 5; // 柱体间距
public static final int ANIMATION_DELAY = 10; // 动画延迟时间(毫秒)
public static final int MOVE_DISTANCE = 5; // 平移距离
public static final int NAME_SIZE = 15; // 数据数组大小
public int[] data; // 存储数据的数组
public int currentIndex = 0; // 当前排序的索引
public int swapIndex1 = -1; // 待交换的第一个索引
public int swapIndex2 = -1; // 待交换的第二个索引
public int swapDistance = 0; // 交换的距离
public int count = 1; // 计数器
public SelectionSortVisualization() {
// 设置面板大小等属性
setPreferredSize(new Dimension(WIDTH, HEIGHT));
data = new int[NAME_SIZE];
}
public void selectionSort() {
// 创建新线程进行选择排序,并在排序过程中更新可视化界面
new Thread(() -> {
for (int i = 0; i < data.length - 1; i++) {
int minIndex = i;
for (int j = i + 1; j < data.length; j++) {
if (data[j] < data[minIndex]) {
minIndex = j;
}
}
swap(i, minIndex);
currentIndex = i;
repaint();
sleep(ANIMATION_DELAY);
}
currentIndex = data.length - 1;
repaint();
}).start();
}
public void swap(int index1, int index2) {
// 实现交换过程的动画效果
// 设置要交换的索引
swapIndex1 = index1;
swapIndex2 = index2;
// 计算交换距离和方向
int distance = (BAR_WIDTH + BAR_SPACING) * Math.abs(index2 - index1);
int direction = (index2 > index1) ? 1 : -1;
// 交换过程的动画效果:将交换的两个柱体进行平移
for (int i = 0; i <= distance; i += MOVE_DISTANCE) {
swapDistance = i * direction; // 设置平移距离
repaint(); // 重绘界面,展示平移效果
sleep(ANIMATION_DELAY); // 线程休眠,控制动画速度
}
// 执行实际的交换操作
int temp = data[index1];
data[index1] = data[index2];
data[index2] = temp;
// 打印当前排序结果
System.out.print("第" + count + "次排序结果:");
count++;
for (int i = 0; i < data.length; i++) {
System.out.print(data[i]);
if (i < data.length - 1) {
System.out.print(", ");
}
}
System.out.println();
// 重置交换的索引和平移距离
swapIndex1 = -1;
swapIndex2 = -1;
swapDistance = 0;
}
public void sleep(int delay) {
try {
Thread.sleep(delay);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void paintComponent(Graphics g) {
// 绘制可视化界面
super.paintComponent(g);
g.setColor(Color.WHITE);
g.fillRect(0, 0, WIDTH, HEIGHT);
int x = 50;
int y = HEIGHT - 300;
int minData = Arrays.stream(data).min().orElse(0); // 获取数组中的最小值
int maxData = Arrays.stream(data).max().orElse(0); // 获取数组中的最大值
// 创建一个数组,用于存储每个柱体的x坐标
int[] barXs = new int[data.length];
for (int i = 0; i < data.length; i++) {
barXs[i] = x;
x += BAR_WIDTH + BAR_SPACING;
}
for (int i = 0; i < data.length; i++) {
if (i == swapIndex1 || i == swapIndex2) {
g.setColor(Color.RED);
} else if (i <= currentIndex) {
g.setColor(Color.GREEN);
} else {
g.setColor(Color.BLUE);
}
int barHeight;
int barY;
if (data[i] >= 0) {
// 处理正数的情况
barHeight = (int) ((double) data[i] / maxData * (HEIGHT - 100));
// 调整柱体高度为原来的一半
barHeight /= 2;
barY = y - barHeight;
} else {
// 处理负数的情况
barHeight = (int) ((double) Math.abs(data[i]) / Math.abs(minData) * (HEIGHT - 100));
barHeight /= 6;
barY = y;
}
// 根据是否是需要交换的柱体来调整其x坐标
int barX = barXs[i];
if (i == swapIndex1) {
barX += swapDistance;
} else if (i == swapIndex2) {
barX -= swapDistance;
}
g.fillRect(barX, barY, BAR_WIDTH, barHeight);
g.setColor(Color.BLACK);
g.drawRect(barX, barY, BAR_WIDTH, barHeight);
// 在柱体下方绘制数字
g.setColor(Color.BLACK);
FontMetrics metrics = g.getFontMetrics();
int stringWidth = metrics.stringWidth(Integer.toString(data[i]));
int stringHeight = metrics.getAscent();
int stringX = barX + (BAR_WIDTH - stringWidth) / 2;
int stringY = barY + barHeight + stringHeight;
g.drawString(Integer.toString(data[i]), stringX, stringY);
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
SelectionSortVisualization visualization = new SelectionSortVisualization();
JFrame frame = new JFrame("选择排序可视化");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(visualization, BorderLayout.CENTER);
// 添加说明标签
JLabel label = new JLabel("输入 " + NAME_SIZE + " 个用空格分隔的整数:");
JTextField inputField = new JTextField(20);
JButton sortButton = new JButton("Sort");
sortButton.addActionListener(e -> {
String input = inputField.getText();
String[] numbers = input.split("\\s+");
if (numbers.length != NAME_SIZE) {
JOptionPane.showMessageDialog(frame, "请输入" + NAME_SIZE + " 用空格分隔的整数.");
return;
}
for (int i = 0; i < NAME_SIZE; i++) {
visualization.data[i] = Integer.parseInt(numbers[i]);
}
visualization.selectionSort();
});
// 添加输入面板
JPanel inputPanel = new JPanel();
inputPanel.add(label);
inputPanel.add(inputField);
inputPanel.add(sortButton);
frame.add(inputPanel, BorderLayout.NORTH);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
});
}
}
算法课程设计,java动态实现选择排序,带UI画面
最新推荐文章于 2024-07-25 21:13:04 发布