排序算法动画Java实现

排序算法动画实现

最近浏览B站,看到一些排序算法动画的作品,很是好玩。排序算法动画可以帮助我们更好地了解,算法的原理。最近也摸索了一下,使用java实现了排序算法动画。话不多说先看效果再上代码。

0、效果图

在这里插入图片描述

1、使用swing与awt实现绘制数组矩形

import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferStrategy;
import java.util.Date;
import java.util.HashSet;
import java.util.Random;
import java.util.Set;

public class DynamicCanvasExample implements Runnable {

    private JFrame frame;
    private MyCanvas canvas;
    private int[] arr;
    // 用于保存两个要交换位置的元素下标
    private int[] arrColor = new int[2];
    private Set<Integer> set = new HashSet<>();

    public DynamicCanvasExample() {
        int n = 500;
        arr = new int[n];
        Random random = new Random(123L);
        for (int i = 0; i < n; i++) {
            arr[i] = random.nextInt(n);
        }
        canvas = new MyCanvas();
        frame = new JFrame();
        frame.getContentPane().add(canvas);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        // 获取当前屏幕尺寸
        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        frame.setBounds(0, 0, (int) screenSize.getWidth(), (int) screenSize.getHeight());
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        new Thread(new DynamicCanvasExample()).start();
    }

    @Override
    public void run() {
        long start = new Date().getTime();
        new QuickSort().quickSort(arr, arrColor, canvas);
        // 排序完毕重新刷色
        for (int i = 0; i < arr.length; i++) {
            set.add(i);
            repaint(1);
        }
        System.out.println(new Date().getTime() - start);
    }

    public void repaint(long millins) {
        try {
            Thread.sleep(millins);
            canvas.repaint();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    class MyCanvas extends Canvas {
        @Override
        public void update(Graphics g) {
            paint(g);
        }

        @Override
        public void paint(Graphics g) {
            // 使用双缓冲技术进行绘制,避免重绘时,画布闪烁
            BufferStrategy bs = getBufferStrategy();
            if (bs == null) {
                createBufferStrategy(2);
                return;
            }
            Graphics2D g2d = (Graphics2D) bs.getDrawGraphics();
            g2d.clearRect(0, 0, getWidth(), getHeight());

            for (int i = 0; i < arr.length; i++) {
                if (i == arrColor[0] || i == arrColor[1]) {
                    g2d.setColor(Color.RED);
                } else {
                    g2d.setColor(Color.BLUE);
                }
                if (set.contains(i)) {
                    g2d.setColor(Color.orange);
                }
                // 绘制矩形,执行x,y,w,h,h为数组元素大小,可以自己调整
                g2d.drawRect(i * 3 + 3, 900, 5, -arr[i]);
            }
            g2d.dispose();
            bs.show();
        }
    }

}

2、实现快速排序动画

这里仅以最喜欢的快排为例,其他排序算法可根据需要实现


import java.awt.*;

public class QuickSort {

    private Canvas canvas;
    private int[] arrColor;
    private long millis = 1L; // 重绘睡眠时间

    public void quickSort(int[] arr, int[] arrColor, Canvas canvas) {
        this.canvas = canvas;
        this.arrColor = arrColor;
        quick(arr, 0, arr.length - 1);
        // 排序完毕,取消交换位置元素的颜色
        repaint(millis, -1, -1);
    }

    public void quick(int[] arr, int l, int r) {
        if (l >= r) return;
        int base = arr[l];
        int low = l;
        int high= r;
        while (low < high) {
            // 每次循环都加repaint是为了更好的模拟时间复杂度
            while (arr[high] >= base && high > low) {
                high--;
                repaint(millis, low, high);
            }
            if (high > low) {
                arr[low++] = arr[high];
                repaint(millis, low, high);
            }
            while (arr[low] <= base && high > low) {
                low++;
                repaint(millis, low, high);
            }
            if (high > low) {
                arr[high--] = arr[low];
                repaint(millis, low, high);
            }
        }
        arr[low] = base;
        quick(arr, l, low - 1);
        quick(arr, high + 1, r);
    }

    /**
     * @param millins 睡眠时间(ms)
     * @param low 交换位置元素的下标
     * @param high 交换位置元素的下标
     */
    public void repaint(long millins, int low, int high) {
        try {
            // 睡眠是为了看到动画效果,不然一瞬间就排完了
            Thread.sleep(millins);
            arrColor[0] = low;
            arrColor[1] = high;
            canvas.repaint();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

3、注意事项

改案例只对,空间复杂度为O(1)的算法有效,对于空间复杂度为O(n)的归并排序,则不容易改造

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值