算法课程设计,java动态实现选择排序,带UI画面

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);
        });
    }
}

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值