java 可视化冒泡排序

1. 效果

(清除原有内容时会有闪屏 后面看看怎么搞)

1. gif

效果
(录到结束的)
在这里插入图片描述

2. 开始

在这里插入图片描述

3. 结束

在这里插入图片描述

2. 代码

2.1 定制数组 (会触发数组元素变更的事件)

继承自ArrayList 重载 set 方法 当调用 set 函数时 释放 set事件

public class MyArray<T> extends ArrayList<T> {

    private List<OnChange<T>> listeners;

    public MyArray (List<OnChange<T>> listeners, List<T> ori) {
        super(ori);
        this.listeners = listeners;
        doNotify(l -> l.onInit(ori));
    }

    @Override
    public T set(int i, T ele) {
        T old = super.set(i, ele);
        doNotify(l -> l.onSet(i, old, ele));
        return old;
    }

    private void doNotify(Consumer<OnChange<T>> consumer) {
        listeners.forEach(consumer);
    }

    public static interface OnChange<T> {

        void onSet(int i, T old, T news);

        void onInit(List<T> ele);
    }
}

2. 绘图程序

实现上述数组的 onChange 接口 监听元素变更 以重新绘制

public class VisualArray extends JPanel implements MyArray.OnChange<Integer> {

    private List<Integer> data;
    private volatile Graphics graphics;
    private int rectWidth;
    private int totalHeight = 800;
    private int totalWidth = 1006;

    public VisualArray() {
         // 窗口初始化
        JFrame jFrame = new JFrame();
        jFrame.setContentPane(this);
        jFrame.setTitle("可视化数组");
        jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        jFrame.setSize(totalWidth, this.totalHeight);
        jFrame.setVisible(true);

    }

    @Override
    public void paint(Graphics graphics) {
        super.paint(graphics);
        this.graphics = graphics;
        this.drawAll();
    }

    @Override
    public void onSet(int i, Integer old, Integer news) {
        this.data.set(i , news);
        this.paint(this.graphics);
        // 等待一段时间 方便观察效果
        try {
            Thread.sleep(200);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private double rectHeightRate;
    private final int xStart = 73;

    @Override
    public void onInit(List<Integer> ele) {
        this.data = new ArrayList<>(ele);
        int size = this.data.size();

        int leftWidth = totalWidth - (int)(this.xStart * 2.2);
        this.rectWidth = leftWidth / size;

        int maxVal = this.data.stream().max(Comparator.comparing(Integer::intValue)).get();
        this.rectHeightRate = (this.totalHeight * 0.85) / maxVal;
        this.paint(this.graphics);
    }
   
    // 绘制数组所有的元素
    private void drawAll() {
        graphics.clearRect(0, 0, this.totalWidth, this.totalHeight);
        if (null == this.data || this.data.size() == 0) {
            return;
        }

        BasicStroke basicStroke = new BasicStroke(10.1f,BasicStroke.CAP_ROUND, BasicStroke.JOIN_BEVEL);
        ((Graphics2D)this.graphics).setStroke(basicStroke);
        int startColor = 0x00ff00;

        for (int i = 0; i < this.data.size(); i++) {
            this.graphics.setColor(new Color(startColor));
            int height = (int) (this.data.get(i) * this.rectHeightRate);
            this.graphics.fillRect(this.xStart + i * this.rectWidth, totalHeight - height, this.rectWidth, height);
            startColor += 16;
        }

        this.updateUI();
    }

}

3. 主方法

public class MainVisualSort {

    private boolean needSwap(int i, int j) {
        return i < j;
    }
    
    // 冒泡排序
    public void bubbleSort(List<Integer> list) {

        for (int i = 0; i < list.size(); i++) {
            for (int j = i + 1; j < list.size(); j++) {
                if (needSwap(list.get(j), list.get(i))) {
                    list.set(j, list.set(i, list.get(j)));
                }
            }
        }
    }

    public static void main(String[] args) {
        MainVisualSort mainVisualSort = new MainVisualSort();

        VisualArray visualArray = new VisualArray();
        // 等待 swing 初始化好
        try{
            Thread.sleep(200);
        } catch (Exception e) {
            e.printStackTrace();
        }
        // 随机40个元素
        List<Integer> toDeal = new ArrayList<>();
        for (int i = 0; i < 40; i++) {
            toDeal.add(Math.abs(new Random().nextInt(71)) + 30);
        }
        List<Integer> list = new MyArray<>(Collections.singletonList(visualArray), toDeal);
        mainVisualSort.bubbleSort(list);
    }
}

如果要观察快排效果 再实现一个 main 类中再加一个 quickSort方法即可
其余不需要改动