算法排序可视化

算法排序可视化(选择排序为例)

实现效果
在这里插入图片描述

package Sort;

import java.awt.*;
import javax.swing.*;

public class AlgoFrame extends JFrame {

	private int canvasWidth;
	private int canvasHeight;

	public AlgoFrame(String title, int canvasWidth, int canvasHeight) {

		super(title);

		this.canvasWidth = canvasWidth;
		this.canvasHeight = canvasHeight;

		AlgoCanvas canvas = new AlgoCanvas();
		setContentPane(canvas);

		setResizable(false);
		pack(); // 在setResizable(false)后进行pack(),防止在Windows下系统修改frame的尺寸

		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setVisible(true);
	}

	public AlgoFrame(String title) {

		this(title, 1024, 768);
	}

	// 接口方法
	public int getCanvasWidth() {
		return canvasWidth;
	}

	public int getCanvasHeight() {
		return canvasHeight;
	}

	// TODO: 设置自己的数据
	private SelectionSortData data;
	

	public void render(SelectionSortData data) {
		this.data = data; //
		repaint();
	}

	// 自定义面板类
	private class AlgoCanvas extends JPanel {

		public AlgoCanvas() {
			// 双缓存
			super(true);
		}

		@Override
		public void paintComponent(Graphics g) {
			super.paintComponent(g);

			Graphics2D g2d = (Graphics2D) g;

			// 抗锯齿
			RenderingHints hints = new RenderingHints(RenderingHints.KEY_ANTIALIASING,
					RenderingHints.VALUE_ANTIALIAS_ON);
			hints.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
			g2d.addRenderingHints(hints);

			// 具体绘制
			// TODO: 绘制自己的数据data
			
			int w=canvasWidth/data.N();
			for(int i=0;i<data.N();i++){
				/*AlgoVisHelper.setColor(g2d, AlgoVisHelper.LightBlue);
				AlgoVisHelper.fillRectangle(g2d, i*w, canvasHeight-data.get(i), w-1, data.get(i));*/
				 //
				//已经排好
				if(i<data.getOrderedIndex()){
					AlgoVisHelper.setColor(g2d, AlgoVisHelper.Red);
				}else{
					AlgoVisHelper.setColor(g2d, AlgoVisHelper.Grey);
				}
				//当前比较元素
				if(i==data.getCurrentCompareIndex()){
					AlgoVisHelper.setColor(g2d, AlgoVisHelper.LightBlue);
				}
				//当前最小值
				if(i == data.currentMinIndex)
					AlgoVisHelper.setColor(g2d, AlgoVisHelper.Indigo);
	  AlgoVisHelper.fillRectangle(g2d, i * w, canvasHeight-data.get(i), w - 1, data.get(i));
					}
				
		}

		// 设置画布的大小
		@Override
		public Dimension getPreferredSize() {
			return new Dimension(canvasWidth, canvasHeight);
		}
	}
}


2

package Sort;

import javax.swing.*;
import java.awt.*;
import java.awt.geom.*;

import java.lang.InterruptedException;

public class AlgoVisHelper {

	private AlgoVisHelper() {
	}
	// 常用颜色
	public static final Color Red = new Color(0xF44336);
	public static final Color Pink = new Color(0xE91E63);
	public static final Color Purple = new Color(0x9C27B0);
	public static final Color DeepPurple = new Color(0x673AB7);
	public static final Color Indigo = new Color(0x3F51B5);
	public static final Color Blue = new Color(0x2196F3);
	public static final Color LightBlue = new Color(0x03A9F4);
	public static final Color Cyan = new Color(0x00BCD4);
	public static final Color Teal = new Color(0x009688);
	public static final Color Green = new Color(0x4CAF50);
	public static final Color LightGreen = new Color(0x8BC34A);
	public static final Color Lime = new Color(0xCDDC39);
	public static final Color Yellow = new Color(0xFFEB3B);
	public static final Color Amber = new Color(0xFFC107);
	public static final Color Orange = new Color(0xFF9800);
	public static final Color DeepOrange = new Color(0xFF5722);
	public static final Color Brown = new Color(0x795548);
	public static final Color Grey = new Color(0x9E9E9E);
	public static final Color BlueGrey = new Color(0x607D8B);
	public static final Color Black = new Color(0x000000);
	public static final Color White = new Color(0xFFFFFF);

	// 绘制空心圆
	public static void strokeCircle(Graphics2D g, int x, int y, int r) {

		Ellipse2D circle = new Ellipse2D.Double(x - r, y - r, 2 * r, 2 * r);
		g.draw(circle);
	}

	// 绘制实心圆
	public static void fillCircle(Graphics2D g, int x, int y, int r) {

		Ellipse2D circle = new Ellipse2D.Double(x - r, y - r, 2 * r, 2 * r);
		g.fill(circle);
	}

	// 绘制空心矩形
	public static void strokeRectangle(Graphics2D g, int x, int y, int w, int h) {

		Rectangle2D rectangle = new Rectangle2D.Double(x, y, w, h);
		g.draw(rectangle);
	}

	// 绘制实心矩形
	public static void fillRectangle(Graphics2D g, int x, int y, int w, int h) {

		Rectangle2D rectangle = new Rectangle2D.Double(x, y, w, h);
		g.fill(rectangle);
	}

	// 设置画笔颜色
	public static void setColor(Graphics2D g, Color color) {
		g.setColor(color);
	}

	// 设置画笔粗细
	public static void setStrokeWidth(Graphics2D g, int w) {
		int strokeWidth = w;
		g.setStroke(new BasicStroke(strokeWidth, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
	}

	// 暂停t毫秒
	public static void pause(int t) {
		try {
			Thread.sleep(t);
		} catch (InterruptedException e) {
			System.out.println("Error sleeping");
		}
	}

	// 放置图片
	public static void putImage(Graphics2D g, int x, int y, String imageURL) {

		ImageIcon icon = new ImageIcon(imageURL);
		Image image = icon.getImage();

		g.drawImage(image, x, y, null);
	}

	// 放置文本
	public static void drawText(Graphics2D g, String text, int centerx, int centery) {

		if (text == null)
			throw new IllegalArgumentException("Text is null in drawText function!");

		FontMetrics metrics = g.getFontMetrics();
		int w = metrics.stringWidth(text);
		int h = metrics.getDescent();
		g.drawString(text, centerx - w / 2, centery + h);
	}
}

3

package Sort;

import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.lang.reflect.Array;

public class AlgoVisualizer {
	private static int DELAY = 20;
		// TODO: 创建自己的数据
	private SelectionSortData data; // 数据
	private AlgoFrame frame; // 视图
   
	
	 private void setData(int orderedIndex,int currentCompareIndex,int currentMinIndex){
		 data.orderedIndex = orderedIndex;
		 data.currentCompareIndex = currentCompareIndex;
		 data.currentMinIndex = currentMinIndex;
		 frame.render(data);
		 AlgoVisHelper.pause(DELAY);
	 }
	public AlgoVisualizer(int sceneWidth, int sceneHeight,int N) {

		// 初始化数据
		// TODO: 初始化数据
         data =new SelectionSortData(N, sceneHeight); //有N个数 ,最大值不超过屏幕的高度
		// 初始化视图
		EventQueue.invokeLater(() -> {
			frame = new AlgoFrame("Welcome", sceneWidth, sceneHeight);
			// TODO: 根据情况决定是否加入键盘鼠标事件监听器
			frame.addKeyListener(new AlgoKeyListener());
			frame.addMouseListener(new AlgoMouseListener());
			new Thread(() -> {
				run();
			}).start();
		});
	}

	// 动画逻辑
	private void run() {
		/*frame.render(data);
		AlgoVisHelper.pause(DELAY);
		
		for(int i=0;i<data.N();i++){ ///  选择排序
			int min =i;
			frame.render(data);
			AlgoVisHelper.pause(DELAY);
			for(int  j=i+1;j<data.N();j++){///  2
				if(data.get(j)<data.get(min)){ //  3
					frame.render(data);
					AlgoVisHelper.pause(DELAY);
				}
			}
			data.swap(i, min);
			frame.render(data);
			AlgoVisHelper.pause(DELAY);*/
		
		/* frame.render(data); //插入排序
		 AlgoVisHelper.pause(DELAY);
		  for(int i=0;i<data.N()-1;i++){ ///
			    frame.render(data);
				AlgoVisHelper.pause(DELAY);
			  for(int j=0;j<=i;j++){ ///  
				  if(data.get(i+1)<data.get(j)){ ///
					  data.swap(i+1, j);
					  frame.render(data);
						AlgoVisHelper.pause(DELAY);
				  }
			  }
		}*/
		// frame.render(data); //冒泡排序
		 //AlgoVisHelper.pause(DELAY);
		/*setData(0, -1, -1);
		  for(int i=0;i<data.N()-1;i++){ ///bubuSort
			  int minIndex =i;
			  for(int j=0;j<data.N()-i-1;j++){ ///  
				  if(data.get(j+1)<data.get(j)){ ///
					  data.swap(j+1, j);
					  setData(i + 1, -1, -1);
				  }
			  }
		}*/
		 setData(0, -1, -1);
		  for (int i = 0; i < data.N(); i++) {
		  // 寻找[i, n)区间里的最小值的索引
		  int minIndex = i;
		  setData(i, -1, minIndex);
		  for (int j = i + 1; j < data.N(); j++) {
		  setData(i, j, minIndex);
		  if (data.get(j) < data.get(minIndex)) {
		  minIndex = j;
		  setData(i, j, minIndex);
		  }
		  }
		  data.swap(i, minIndex);
		  // 数据交换后进行一次渲染
		  setData(i + 1, -1, -1);
		  }
		  // 排序完成后再进行一次渲染
		  setData(data.N(), -1, -1);
		// TODO: 编写自己的动画逻辑
	}

	// TODO: 根据情况决定是否实现键盘鼠标等交互事件监听器类
	private class AlgoKeyListener extends KeyAdapter {
	}

	private class AlgoMouseListener extends MouseAdapter {
	}

	public static void main(String[] args) {

		int sceneWidth = 800;
		int sceneHeight = 800;
        int N=100;
		// TODO: 根据需要设置其他参数,初始化visualizer
		AlgoVisualizer visualizer = new AlgoVisualizer(sceneWidth, sceneHeight,	N);
	}
}

4

package Sort;
/*
 * dao层
 */
public class SelectionSortData {
   private int []numbers;
   int orderedIndex =-1 ; //[0...orderedIndex) 是有序的
    int currentCompareIndex = -1; // 当前正在比较的元素索引
    int currentMinIndex = -1; // 当前找到的最小元素的索引
   //随机生层N个元素的数组,最大值不超过randomBound
   
   public SelectionSortData(int N,int randomBound){
	   numbers =new int[N];
	   for(int i=0;i<N;i++){
		   numbers[i]= (int)(Math.random()*randomBound)+1; 
	   }
   }
   public int getOrderedIndex() {
	return orderedIndex;
}
public void setOrderedIndex(int orderedIndex) {
	this.orderedIndex = orderedIndex;
}
public int getCurrentCompareIndex() {
	return currentCompareIndex;
}
public void setCurrentCompareIndex(int currentCompareIndex) {
	this.currentCompareIndex = currentCompareIndex;
}
public int getCurrentMinIndex() {
	return currentMinIndex;
}
public void setCurrentMinIndex(int currentMinIndex) {
	this.currentMinIndex = currentMinIndex;
}
//获取长度
   public int N(){
	   return numbers.length;
   }
   public int get(int index){
	   if( index < 0 || index >= numbers.length)
	     throw new IllegalArgumentException("Invalid index to accessSort Data.");  
	   
	return numbers[index];  
   }
   //将索引为i的值和索引为j的值进行交换
   public void swap(int i,int j){
	   if(i<0||i>=numbers.length||j<0||j>=numbers.length){
		   throw new IllegalArgumentException("invalid index to access");
	   }
	   int num =numbers[i];
	   numbers[i]=numbers[j];
	   numbers[j]=num;
   }
   
   
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

金石不渝

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值