排序算法动画实现
最近浏览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)的归并排序,则不容易改造