0.用到的jar包

jcommon-1.0.16.jar、jfreechart-1.0.13.jar

1.实现思路

自定义一个类---用于存放排序算法的操作状态--SortEntity

定义一个方法类---定义一个List<SortEntity>,存放当前排序的算法所有的时刻的状态值---SortUtils

定义一个工具类---传入一个SortEntity,根据SortEntity构建一个JPanel

在UI中通过线程来循环遍历List<SortEntity>,实现动画

3.SortEntity的定义

package com.edusys.utils;

import java.util.Arrays;

public class SortEntity {
public int[] dataList=new int[20];
public int index_i;
public int index_j;
public int pivot=0; public int[] getDataList() {
return dataList;
}
public void setDataList(int[] dataList) {
for(int i=0;i<dataList.length;i++){
this.dataList[i] = dataList[i];
}
}
public int getIndex_i() {
return index_i;
}
public void setIndex_i(int index_i) {
this.index_i = index_i;
}
public int getIndex_j() {
return index_j;
}
public void setIndex_j(int index_j) {
this.index_j = index_j;
}
public int getPivot() {
return pivot;
}
public void setPivot(int pivot) {
this.pivot = pivot;
} public SortEntity() {
}
public SortEntity(int[] dataList, int index_i, int index_j, int pivot) {
for(int i=0;i<dataList.length;i++){
this.dataList[i] = dataList[i];
}
this.index_i = index_i;
this.index_j = index_j;
this.pivot = pivot;
} @Override
public String toString() {
return "SortEntity [dataList=" + Arrays.toString(dataList) + ", index_i=" + index_i + ", index_j=" + index_j
+ ", pivot=" + pivot + "]";
} }

PS:这里填个坑,数组赋值时不能直接赋值,必须进行拷贝

this.dataList=dataList;
替换为:
for(int i=0;i<dataList.length;i++){
this.dataList[i] = dataList[i];
}

否则拷贝出的只是一个长度为传入长度的有序数组:[1,2,3,4,5......]

4.SortUtils的定义

package com.edusys.utils;

import java.util.ArrayList;
import java.util.List; public class SortUtils {
private static int length=20;
private int[] dataList;
private List<SortEntity> quickList=new ArrayList<SortEntity>();;
private List<SortEntity> bubbleList=new ArrayList<SortEntity>();;
private List<SortEntity> shellList=new ArrayList<SortEntity>();; public int[] getDataList() {
return dataList;
} public void setDataList() {
dataList = new int[length]; boolean flag=false;
int temp;
int index = 0;
while(index < length){
temp = (int)(Math.random()*length)+1;
//Check the same element
for(int j=0;j<index;j++){
if(temp == dataList[j]){
flag=true;
break;
}
else{
flag = false;
}
}
if(!flag ){
dataList[index++] = temp;
}
}
} /**
* 对初始数组进行赋值
*/
public SortUtils(){
setDataList();
}
/**
* 得到快速排序的结果集
* @return
*/
public List<SortEntity> getQuickList(){
quickSort(getDataList(),0,length-1);
return quickList;
} /**
* 得到冒泡排序结果集
* @return
*/
public List<SortEntity> getBubbleList() {
bubbleList.add(new SortEntity(getDataList(), 0, 1, 0));
bubbleSort(getDataList()); return bubbleList;
} /**
* 得到希尔排序的结果集
* @return
*/
public List<SortEntity> getShellList() {
shellList.add(new SortEntity(getDataList(), 0, 1, 0));
shellSort(getDataList());
return shellList;
} /**
* 快速排序
* @param a
* @param left
* @param right
*/
public void quickSort(int[] arr,int left,int right) {
if(left>right){
return;
}
int pivot=arr[left];
quickList.add(new SortEntity(arr, left, right, pivot)); //定义基准值为数组第一个数
int i=left;
int j=right;
while(i<j) {
//从右往左找比基准值小的数
while(pivot<=arr[j]&&i<j){
j--;
quickList.add(new SortEntity(arr, left, right, pivot));
}
//从左往右找比基准值大的数
while(pivot>=arr[i]&&i<j){
i++;
quickList.add(new SortEntity(arr, left, right, pivot));
}
//如果i<j,交换它们
if(i<j){
int temp=arr[i];
arr[i]=arr[j];
arr[j]=temp;
quickList.add(new SortEntity(arr, left, right, pivot));
}
}
//把基准值放到合适的位置
arr[left]=arr[i];
arr[i]=pivot;
//对左边的子数组进行快速排序
quickSort(arr,left,i-1);
//对右边的子数组进行快速排序
quickSort(arr,i+1,right);
}
/**
* 冒泡排序
* @param arr
*/
public void bubbleSort(int[] arr){
for(int i=0;i<arr.length-1;i++){//外层循环控制排序趟数
for(int j=0;j<arr.length-1-i;j++){//内层循环控制每一趟排序多少次
if(arr[j]>arr[j+1]){
int temp=arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
}
bubbleList.add(new SortEntity(arr, i, j, 0));
}
}
}
/**
* 希尔排序
* @param arr
*/
public void shellSort(int[] arr){
//增量
int incrementNum = arr.length/2;
while(incrementNum >=1){
for(int i=0;i<arr.length;i++){
//进行插入排序
for(int j=i;j<arr.length-incrementNum;j=j+incrementNum){
if(arr[j]>arr[j+incrementNum]){
int temple = arr[j];
arr[j] = arr[j+incrementNum];
arr[j+incrementNum] = temple;
}
shellList.add(new SortEntity(arr, i, j, 0));
}
}
//设置新的增量
incrementNum = incrementNum/2;
}
}
}

此方法可以定义多个List<SortEntity>,实现各种不同的算法排序

5.HistogramUtils的实现

package com.edusys.utils;

import java.awt.Font;

import javax.swing.JPanel;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.annotations.CategoryTextAnnotation;
import org.jfree.chart.axis.CategoryAnchor;
import org.jfree.chart.axis.CategoryAxis;
import org.jfree.chart.axis.CategoryLabelPositions;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.renderer.category.BarRenderer;
import org.jfree.chart.title.TextTitle;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.category.DefaultCategoryDataset;
import org.jfree.ui.TextAnchor; public class HistogramUtils { private SortEntity sortEntity; public HistogramUtils(SortEntity sortEntity) {
this.sortEntity=sortEntity;
}
/**
* 创建柱状图数据集
* @return
*/
public CategoryDataset createDataset(){
DefaultCategoryDataset dataset=new DefaultCategoryDataset();
int[] dataList=sortEntity.getDataList();
for(int i=0;i<dataList.length;i++){
if(sortEntity.getIndex_i()==i){
dataset.setValue(sortEntity.getDataList()[i],"", sortEntity.getDataList()[i]+" i");
}else if(sortEntity.getIndex_j()==i){
dataset.setValue(sortEntity.getDataList()[i],"", sortEntity.getDataList()[i]+" j");
}else{
dataset.setValue(sortEntity.getDataList()[i],"", sortEntity.getDataList()[i]+"");
}
} return dataset;
}
/**
* 用数据集创建一个图表
* @param dataset
* @return
*/
public JFreeChart createChart(CategoryDataset dataset){
JFreeChart chart=ChartFactory.createBarChart("", "","", dataset, PlotOrientation.VERTICAL, true, true, false); //创建一个JFreeChart
chart.setTitle(new TextTitle("",new Font("宋体",Font.BOLD+Font.ITALIC,40)));//可以重新设置标题,替换“hi”标题
CategoryPlot plot=(CategoryPlot)chart.getPlot();//获得图标中间部分,即plot
CategoryAxis categoryAxis=plot.getDomainAxis();//获得横坐标
categoryAxis.setLabelFont(new Font("微软雅黑",Font.BOLD,10));//设置横坐标字体
categoryAxis.setMaximumCategoryLabelWidthRatio(2f);
categoryAxis.setCategoryLabelPositions(CategoryLabelPositions.DOWN_90);
return chart;
}
/**
* 生成一个Jpanel
* @return
*/
public JPanel createPanel(){
JFreeChart chart =createChart(createDataset());
CategoryPlot categoryplot =(CategoryPlot)chart.getCategoryPlot();
BarRenderer renderer = new CustomRenderer(sortEntity.getIndex_i(), sortEntity.getIndex_j());
//在柱子上显示相应信息
renderer.setBaseItemLabelsVisible(true);
CategoryTextAnnotation a = new CategoryTextAnnotation("_________________________________________________________", "", sortEntity.getPivot());
a.setCategoryAnchor(CategoryAnchor.START);
a.setFont(new Font("SansSerif", Font.PLAIN, 12));
a.setTextAnchor(TextAnchor.BOTTOM_LEFT);
categoryplot.addAnnotation(a);
categoryplot.setRenderer(renderer);
return new ChartPanel(chart); //将chart对象放入Panel面板中去,ChartPanel类已继承Jpanel
}
}

这个使用的是JFreeChart 来进行构图的,具体的百度参考,需要的jar在文章的开头处

5.1自定义的BarRenderer

package com.edusys.utils;

import java.awt.Color;
import java.awt.Paint; import org.jfree.chart.renderer.category.IntervalBarRenderer; public class CustomRenderer extends IntervalBarRenderer {
private int index_i,index_j;
private Paint[] colors; public CustomRenderer(int index_i,int index_j) {
this.index_i=index_i;
this.index_j=index_j;
colors = new Paint[3];
colors[0]=Color.RED;
colors[1]=Color.RED;
colors[2]=Color.GREEN;
} public CustomRenderer() {
super();
} //对i,j赋予不同于其他柱子的颜色
public Paint getItemPaint(int i, int j) {
if(j==index_i){
return colors[0];
}else if(j==index_j){
return colors[1];
}else {
return colors[2];
}
}
}

这里重写BarRenderer 类是为了对每次状态中的i,j进行特殊颜色处理,并规范JFreeChart 构图中的颜色

6.实现类

package com.edusys.ui;

import java.awt.Dimension;
import java.awt.Font;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List; import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JSlider;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.ScrollPaneConstants;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener; import com.edusys.utils.FileUtils;
import com.edusys.utils.HistogramUtils;
import com.edusys.utils.SortEntity;
import com.edusys.utils.SortUtils;
import com.edusys.utils.TimeUtils; public class MainUI { private static int sort_type=0;
private static int speed=1;
private static int sleeptime=100;
private static int count=0;
private static boolean play_flag=false;
private static boolean start_flag=false;
private static List<SortEntity> sortList; public static void main(String[] args) {
MainUI.animation();
}
/**
* 算法动画演示
*/
public static void animation(){
final JFrame frame=new JFrame(); frame.setSize(1000,620);
frame.setVisible(true);
frame.setResizable(false);
frame.setLocation((Toolkit.getDefaultToolkit().getScreenSize().width-1000)/2,
(Toolkit.getDefaultToolkit().getScreenSize().height-620)/2);
frame.setTitle("Algorithm Teaching System");
frame.setLayout(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); sleeptime=100/speed;
final SortUtils sortUtils=new SortUtils();
if(sort_type==0){
sortList=sortUtils.getQuickList();
}else if(sort_type==1){
sortList=sortUtils.getBubbleList();
}else{
sortList=sortUtils.getShellList();
}
int len=sortList.size(); JPanel jPanel_sort=new JPanel();
HistogramUtils histogramUtils=new HistogramUtils(sortList.get(count));
jPanel_sort=histogramUtils.createPanel();
frame.add(jPanel_sort);
jPanel_sort.setBounds(0, 0, 450, 600); JLabel jLabel_title=new JLabel("Sort Algorithm");
frame.add(jLabel_title);
jLabel_title.setBounds(500, 20, 120, 30);
JRadioButton jRadioButton_quick=new JRadioButton("Qucik Sort");
frame.add(jRadioButton_quick);
if(sort_type==0){
jRadioButton_quick.setSelected(true);
}
jRadioButton_quick.setBounds(500, 50, 120, 30);
jRadioButton_quick.addActionListener(new ActionListener() { @Override
public void actionPerformed(ActionEvent e) {
sort_type=0;
frame.dispose();
MainUI.animation();
}
});
JRadioButton jRadioButton_bubble=new JRadioButton("Bubble Sort");
frame.add(jRadioButton_bubble);
jRadioButton_bubble.setBounds(500, 80, 120, 30);
if(sort_type==1){
jRadioButton_bubble.setSelected(true);
}
jRadioButton_bubble.addActionListener(new ActionListener() { @Override
public void actionPerformed(ActionEvent e) {
sort_type=1;
frame.dispose();
MainUI.animation();
}
});
JRadioButton jRadioButton_shell=new JRadioButton("Shell Sort");
frame.add(jRadioButton_shell);
jRadioButton_shell.setBounds(500, 110, 120, 30);
if(sort_type==2){
jRadioButton_shell.setSelected(true);
}
jRadioButton_shell.addActionListener(new ActionListener() { @Override
public void actionPerformed(ActionEvent e) {
sort_type=2;
frame.dispose();
MainUI.animation();
}
});
ButtonGroup buttonGroup_sort=new ButtonGroup();
buttonGroup_sort.add(jRadioButton_shell);
buttonGroup_sort.add(jRadioButton_bubble);
buttonGroup_sort.add(jRadioButton_quick); JLabel jLabel_speed=new JLabel("Speed");
frame.add(jLabel_speed);
jLabel_speed.setBounds(620, 160, 120, 30); JSlider jSlider_speed = new JSlider(1, 5, 1);
frame.add(jSlider_speed);
jSlider_speed.setBounds(500, 190, 300, 40);
jSlider_speed.setMajorTickSpacing(1);
jSlider_speed.setPaintTicks(true);
jSlider_speed.setPaintLabels(true);
jSlider_speed.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
speed=jSlider_speed.getValue();
sleeptime=100/speed;
}
}); JButton jButton_start=new JButton("Start");
frame.add(jButton_start);
jButton_start.setBounds(500, 320, 80, 30);
jButton_start.addActionListener(new ActionListener() { @Override
public void actionPerformed(ActionEvent e) {
start_flag=true;
new Thread(){
@Override
public void run(){
while (count<len&&start_flag){
//休眠
try {
Thread.sleep(sleeptime);
} catch (InterruptedException e1) {
e1.printStackTrace();
} JPanel jPanel_sort=new JPanel();
HistogramUtils histogramUtils=new HistogramUtils(sortList.get(count));
jPanel_sort=histogramUtils.createPanel();
frame.add(jPanel_sort);
jPanel_sort.setBounds(0, 0, 450, 600);
count++;
}
}
}.start();
jButton_start.setEnabled(false);
}
}); JButton jButton_restart=new JButton("Restart");
frame.add(jButton_restart);
jButton_restart.setBounds(600, 320, 80, 30);
jButton_restart.addActionListener(new ActionListener() { @Override
public void actionPerformed(ActionEvent e) {
frame.dispose();
MainUI.animation();
}
}); JButton jButton_pause=new JButton("Pause");
frame.add(jButton_pause);
jButton_pause.setBounds(700, 320, 80, 30);
jButton_pause.addActionListener(new ActionListener() { @Override
public void actionPerformed(ActionEvent e) {
if(!play_flag){
start_flag=false;
jButton_pause.setText("Play");
play_flag=true;
}else{
start_flag=true;
jButton_pause.setText("Pause");
play_flag=false;
new Thread(){
@Override
public void run(){
while (count<len&&start_flag){
//休眠
try {
Thread.sleep(sleeptime);
} catch (InterruptedException e1) {
e1.printStackTrace();
} JPanel jPanel_sort=new JPanel();
HistogramUtils histogramUtils=new HistogramUtils(sortList.get(count));
jPanel_sort=histogramUtils.createPanel();
frame.add(jPanel_sort);
jPanel_sort.setBounds(0, 0, 450, 600);
count++;
}
}
}.start();
}
}
}); JButton jButton_forward=new JButton("Forward");
frame.add(jButton_forward);
jButton_forward.setBounds(800, 320, 80, 30);
jButton_forward.addActionListener(new ActionListener() { @Override
public void actionPerformed(ActionEvent e) {
if(count<len-1){
count++;
JPanel jPanel_sort=new JPanel();
HistogramUtils histogramUtils=new HistogramUtils(sortList.get(count));
jPanel_sort=histogramUtils.createPanel();
frame.add(jPanel_sort);
jPanel_sort.setBounds(0, 0, 450, 600);
}
}
}); JButton jButton_back=new JButton("Back");
frame.add(jButton_back);
jButton_back.setBounds(900, 320, 80, 30);
jButton_back.addActionListener(new ActionListener() { @Override
public void actionPerformed(ActionEvent e) {
if(count>0){
count--;
JPanel jPanel_sort=new JPanel();
HistogramUtils histogramUtils=new HistogramUtils(sortList.get(count));
jPanel_sort=histogramUtils.createPanel();
frame.add(jPanel_sort);
jPanel_sort.setBounds(0, 0, 450, 600);
}
}
}); JButton jButton_back2menu=new JButton("Back To Menu");
frame.add(jButton_back2menu);
jButton_back2menu.setBounds(700, 360, 120, 30);
jButton_back2menu.addActionListener(new ActionListener() { @Override
public void actionPerformed(ActionEvent e) {
frame.dispose();
MainUI.explanation();
}
}); new Thread(){
@Override
public void run(){
while (count<len&&start_flag){
//休眠
try {
Thread.sleep(sleeptime);
} catch (InterruptedException e1) {
e1.printStackTrace();
} JPanel jPanel_sort=new JPanel();
HistogramUtils histogramUtils=new HistogramUtils(sortList.get(count));
jPanel_sort=histogramUtils.createPanel();
frame.add(jPanel_sort);
jPanel_sort.setBounds(0, 0, 450, 600);
count++;
}
}
}.start();
}
}

这里是实现类,线程上做的不是很好,因为对线程不是很了解,这里我也尝试过用while循环的,但是跳出去之后就不行了,重新打开另外的页面时,会卡死

因此这个线程虽然写的不是很好,但是刚刚能用

代码冗余,见谅!

效果图如下:

aaarticlea/png;base64,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" alt="" />

Java GUI : 实现排序算法的动态演示的更多相关文章

  1. Java中的排序算法(2)

    Java中的排序算法(2) * 快速排序 * 快速排序使用分治法(Divide and conquer)策略来把一个序列(list)分为两个子序列(sub-lists). * 步骤为: * 1. 从数 ...

  2. java实现各种排序算法

    java实现各种排序算法 import java.util.Arrays; public class SomeSort { public static void main(String[] args) ...

  3. Java实现常见排序算法

    常见的排序算法有冒泡排序.选择排序.插入排序.堆排序.归并排序.快速排序.希尔排序.基数排序.计数排序,下面通过Java实现这些排序 1.冒泡排序 package com.buaa; import j ...

  4. Java数组的排序算法

    在Java中,实现数组的排序算法有很多,如冒泡排序法.选择排序法.直接插入法和快速排序法等.下面介绍几种排序算法的具体 实现. 本文引用文献:Java必须知道的300个问题. 1.冒泡排序法 1.1 ...

  5. java实现八大排序算法

    Arrays.sort() 采用了2种排序算法 -- 基本类型数据使用快速排序法,对象数组使用归并排序. java的Collections.sort算法调用的是归并排序,它是稳定排序 方法一:直接插入 ...

  6. java实现折半排序算法

    折半插入排序法,又称二分插入排序法,是直接插入排序法的改良版,也需要执行i-1趟插入,不同之处在于,第i趟插入,先找出第i+1个元素应该插入的的位置,假定前i个数据是已经处于有序状态. 折半插入排序( ...

  7. JAVA简单选择排序算法原理及实现

    简单选择排序:(选出最小值,放在第一位,然后第一位向后推移,如此循环)第一位与后面每一个逐个比较,每次都使最小的置顶,第一位向后推进(即刚选定的第一位是最小值,不再参与比较,比较次数减1) 复杂度: ...

  8. Java 十大排序算法

    目录: 1.冒泡排序(Bubble Sort) 2.选择排序(Selection Sort) 3.插入排序(Insertion Sort) 4.希尔排序(Shell Sort) 5.归并排序(Merg ...

  9. 数据结构Java版之排序算法(二)

    排序按时间复杂度和空间复杂度可分为 低级排序 和 高级排序 算法两种.下面将对排序算法进行讲解,以及样例的展示. 低级排序:冒泡排序.选择排序.插入排序. 冒泡排序: 核心思想,小的数往前移.假设最小 ...

随机推荐

  1. HTML+css基础 css的几种形式 css选择器的两大特性

    3.外联样式 css选择器的两大特性 1.继承性:所有跟文本字体有关的属性都会被子元素继承.且权重是0000. 2.层叠性:就是解决选择器权重大小的一种能力,就是看那个选择器的权重大.谁的权重大听谁的 ...

  2. Python之np.random.permutation()函数的使用

    官网的解释是:Randomly permute a sequence, or return a permuted range. 即随机排列序列,或返回随机范围.我的理解就是返回一个乱序的序列.下面通过 ...

  3. .NET Core 多框架支持(net45+netstandard20)实践中遇到的一些问题总结

    .NET Core 多框架支持(net45+netstandard20)实践中遇到的一些问题总结 前言 本文主要是关于.NET Standard 代码 在多框架 和 多平台 支持自己实践过程中遇到的一 ...

  4. jvm的组成入门

    JVM的组成分为整体组成部分和运行时数据区组成部分. JVM的整体组成 JVM的整体组成可以分为4个部分:类加载器(Classloader).运行时数据区(Runtime Data Area).执行引 ...

  5. 【题解】Ples [COCI2011]

    [题解]Ples [COCI2011] 依旧是没有传送门,只有提供了数据的官网. [题目描述] \(N\) 个汉子和 \(N\) 个妹纸一起参加舞会,跳舞时只能是一个汉子一个妹纸配对,现在给出每个人的 ...

  6. Java中级—转发和重定向的区别

    在设计Web应用程序的时候,经常需要把一个系统进行结构化设计,即按照模块进行划分,让不同的Servlet来实现不同的功能,例如可以让其中一个Servlet接收用户的请求,另外一个Servlet来处理用 ...

  7. elasticsearch ik分词

    elasticsearch 默认并不支持中文分词,默认将每个中文字切分为一个词,这明显不符合我们的业务要求.这里就需要用到ik分词插件. 本文主要囊括了以下几部分,ik插件安装.ik用法介绍.自定义词 ...

  8. Fundebug:JavaScript插件支持错误采样

    Fundebug的付费套餐主要是根据错误事件数制定的,这是因为每一个发送到我们服务器的事件,都会消耗一定的CPU.内存.磁盘以及带宽资源,尤其当错误事件数非常大时,会对我们的计算资源造成很大压力. 如 ...

  9. Linux IO 概念(2)【转】

    转自:https://www.cnblogs.com/qq289736032/p/9188455.html 在上一篇IO底层的概念中杂合了很多模糊的概念,受知识水平的限制,只是从网上抄了很多过来.从l ...

  10. 201871010134-周英杰《面向对象程序设计(java)》第十三周学习总结

    201871010134-周英杰<面向对象程序设计(java)>第十三周学习总结 项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ ...