package com.wfy;
import java.awt.Color;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Random;
/**
* 演示快速排序过程,每一次区间内排序的结果显示
* @author wfy
*
*/
public class ShowQuickSort2 extends Frame{
private static final long serialVersionUID = 741413479566665930L;
/**
* 保存随机生成的整数数组
*/
public int[] s;
/**
* 保存临时顺序的类
*/
private PrintTemp pt = new PrintTemp();
/**
* 当前数组中作为基准值的位置
*/
public int si;
/**
* 跟当前基准值做比较的数值位置
*/
public int sj;
/**
* 生成主窗口
*/
public void ShowFrame(){
this.setSize(640, 480);
setVisible(true);
setTitle("快速排序法-图形演示-wfy");
this.addWindowListener(new WindowAdapter(){
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
public void paint(Graphics g) {
drawBeforeSort(g);
pt.draw(g);
}
/**
* 在排序前重画当前数组并用颜色标注要比较的数
* 要知道当前基准数和被比较数在数组中的位置
* @param g
*/
public void drawBeforeSort(Graphics g){
Color c = g.getColor();
g.setColor(Color.black);
for(int i = 0; i < s.length; i++){
//如果当前位置是基准值,绿色显示
if(i == this.si){
g.setColor(Color.blue);
g.drawString(Integer.toString(s[i]), 26 * i + 20, 40);
g.drawRect(26 * i + 24, 50, 5, s[i]);
g.setColor(Color.black);
}else if(i == this.sj){
g.setColor(Color.red);
g.drawString(Integer.toString(s[i]), 26 * i + 20, 40);
g.drawRect(26 * i + 24, 50, 5, s[i]);
g.setColor(Color.black);
}else{
g.drawString(Integer.toString(s[i]), 26 * i + 20, 40);
g.drawRect(26 * i + 24, 50, 5, s[i]);
}
}
g.setColor(c);
}
/**
* 将每次的循环比较过程显示出来
* @param temp 当前正在排序的区间已经排好顺序的数值的临时存放处
* @param k 当前基准值在temp里的位置
* @param i 当前数组区间的起始坐标,跟j一起确定区间范围
* @param j 当前数组区间的终止坐标
* @param index 当前跟基准值比较的数字在数组中或temp中的位置,如果是排序前则表示在数组中的位置,排序后则表示在temp中的位置
* @param before 为真表示在排序前,已经选择好要用来比较的数字,为假表示已经跟选好的数比较完成
*/
public void draw(List<Integer> temp, int k, int i, int j, int index, boolean before){
if(temp == null && !before){
pt.j = 0;
repaint();
}
pt.list = temp;
/**
* 排序之前,参数index表示要比较的数在数组中的位置
*/
if(before){
this.si = i;
this.sj = index;
}else{
pt.i = i;
pt.j = j;
pt.index = index;
pt.k = k;
}
repaint();
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
/**
* 快速排序过程,针对数组的一段区间
* @param i 起始坐标
* @param j 终止坐标
*/
public void quickSort(int i, int j){
// k 是作为基准值拿出来与区间里的值比较的
int k = s[i];
// length 记录区间的总长度即元素个数
int length = j - i + 1;
// start 记录开始比较的坐标位置
int start = i++;
// temp 排序时会用来临时存放区间内数据
ArrayList<Integer> temp = new ArrayList<Integer>();
temp.add(k);
int left = 0; //记录temp的左边插入位置
int right = length - 1; //当temp的右边插入数据时自动减1
while(left < right){
int index = j;
/**
* 用颜色显示要比较的数
*/
draw(temp, left, start, start + length - 1, index, true);
//先跟右边的数比较
if(k > s[j]){
temp.add(left, s[j]); //把这个数插入到左边插入点
index = left;
left++;
}else{
temp.add(s[j]); //把这个数加入到基准值的后面
index = temp.size() - 1;
right--; //加到基准值的右边所以减1
}
/**
* 跟右边的数字比较后,显示出结果
*/
draw(temp, left, start, start + length - 1, index, false);
index = i;
draw(temp, left, start, start + length - 1, index, true);
/**
* 左右插入位置重叠说明所有数字都比较完成
* 这个时候k在temp里的位置就是left
*/
if(left == right){
break;
}
//再跟左边的数比较
if(k < s[i]){
temp.add(s[i]);
index = temp.size() - 1;
right--;
}else{
temp.add(left, s[i]);
index = left;
left++;
}
i++;
j--;
draw(temp, left, start, start + length-1, index, false);
}
/**
* 此时temp里的顺序就是本次排序后的顺序
* 这个方法保证了基准值左边的数值都比它小,右边的数值都比它大
* 然后按照这个顺序重写区间内的数字
*/
for(int t = 0; t < length; t++){
s[t + start] = temp.get(t);
}
temp = null;
draw(null, 0, 0, 0, 0, false);
/**
* 对temp左边,即基准值k的左边进行排序
* 这样分下去直到区间剩下两个数为止
*/
if(left > 1){
quickSort(start, start + left -1);
}
if(right + 1 < length -1){
quickSort(right + start + 1, start + length - 1);
}
}
public static void main(String args[]){
ShowQuickSort2 qs = new ShowQuickSort2();
qs.ShowFrame();
Random rd = new Random();
int[] s = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
int k = (int)((new Date().getTime() % 240));
for(int i = 0; i < s.length; i++){
s[i] = rd.nextInt(k);
System.out.print(s[i] + " ");
}
qs.s = s;
qs.quickSort(0, s.length - 1);
}
/**
* 用来显示排序过程
* @author wfy
*
*/
class PrintTemp{
/**
* 当前从区间中拿出来的数值的临时存放数组
*/
public List<Integer> list = new ArrayList<Integer>();
/**
* 区间范围的起始坐标
*/
int i;
/**
* 区间范围的终止坐标
*/
int j;
/**
* 基准值在list中的位置,主要是为了打印时用颜色
*/
int k;
/**
* list中新插入值的位置
*/
int index;
public void draw(Graphics g){
if(j == 0){
return;
}
Color c = g.getColor();
g.setColor(Color.black);
int length = list.size();
g.drawLine(26 * i + 18, 40, 26 * i + 18, 480);
g.drawLine(26 * j + 40, 40, 26 * j + 40, 480);
for(int st = 0; st < length; st++){
if(st == k){
g.setColor(Color.blue);
g.drawRect(26 * (st+i) + 24, 250, 5, list.get(st));
g.setColor(Color.black);
}else if(st == index){
g.setColor(Color.red);
g.drawRect(26 * (st+i) + 24, 250, 5, list.get(st));
g.setColor(Color.black);
}else{
g.drawRect(26 * (st+i) + 24, 250, 5, list.get(st));
}
}
g.setColor(c);
}
}
}
分享到:
相关推荐
在这个"快速排序图形界面演示程序"中,用户可以直观地看到快速排序的过程。GUI(图形用户界面)是软件与用户交互的主要方式,它使得用户可以通过鼠标和键盘等输入设备,以图形化的方式操作程序,大大提高了用户体验...
本资源"c#各种排序算法动态图形演示-数据结构经典算法动态演示"显然是一个专注于通过动态图形展示C#中不同排序算法工作原理的教学资料。 首先,让我们深入了解一下几种常见的排序算法: 1. 冒泡排序(Bubble Sort...
2. 快速排序法 快速排序法是一种高效的排序算法,使用分治策略来排序数组。其实现步骤如下: * 选择数组中的一个元素作为枢轴元素。 * 将数组分成两个部分,左边的元素小于枢轴元素,右边的元素大于枢轴元素。 * ...
在本项目中,“快速排序演示程序/vc++/mfc”是一个使用Visual C++和Microsoft Foundation Class (MFC)库编写的程序,目的是通过图形化的方式直观展示快速排序的过程。 MFC是微软提供的一套面向对象的类库,用于简化...
4. **快速排序(Quick Sort)**:快速排序是由C.A.R. Hoare提出的,采用了分治策略。选取一个基准元素,将数组分为两部分,一部分的所有元素都小于基准,另一部分的所有元素都大于基准,然后对这两部分再进行快速...
2. **快速排序**:快速排序是一种效率较高的分治算法,由C.A.R. Hoare在1960年提出。它的基本思想是选取一个基准值,然后将序列分为两部分,一部分的元素都小于基准,另一部分的元素都大于基准,再对这两部分递归...
4. **算法演示**:除了基本操作外,系统还可能提供各种算法的可视化,比如排序算法(冒泡排序、插入排序、选择排序、快速排序、归并排序、堆排序等)和搜索算法(深度优先搜索DFS、广度优先搜索BFS、A*搜索等)。...
3. 对每个非空箱子内的元素进行排序,可以使用其他排序算法,如插入排序、快速排序等。 4. 顺序遍历所有的箱子,将每个箱子中的元素依次添加回原数组,这样就得到了有序的序列。 这个项目对于学习数据结构的学生来...
4. **快速排序**:采用分治策略,选取一个基准值,将数组分为两部分,小于基准的放在左边,大于的放在右边,然后对左右两边递归进行快速排序,平均时间复杂度为O(n log n),最坏情况下为O(n^2)。 5. **归并排序**:...
4. **快速排序**:通过“分治法”策略,选取一个基准元素,将数组分为两部分,使得一部分所有元素小于基准,另一部分所有元素大于基准,然后对这两部分递归地进行快速排序。在图形化展示时,可以体现分区的过程和...
用flash方式演示各种数据结构基础算法3——排序部分,很直观,...里面包括:堆排序.swf,规并排序.swf,基数排序.swf,快速排序.swf,冒泡排序.swf,桶式排序法.swf,希尔排序.swf,直接插入排序.swf,直接选择排序.swf
这里我们将深入探讨五种经典的排序算法:插入排序、归并排序、快速排序、冒泡排序和选择排序,这些算法都在"排序算法演示"项目中有所体现。 1. **插入排序**: 插入排序是一种简单直观的排序算法。它的工作原理是...
"C#排序算法的动态演示系统"是一个教学工具,它以图形化方式展示了C#中常见的排序算法,如冒泡排序、选择排序、插入排序、快速排序、归并排序、堆排序等。通过动态模拟,用户可以直观地看到每一步操作,从而更好地...
本文将深入探讨C#实现的排序算法及其动态演示,主要关注以下几个方面:快速排序、冒泡排序、选择排序、插入排序、归并排序以及希尔排序。 1. **快速排序**:快速排序是一种非常高效的排序算法,由英国计算机科学家C...
2. **快速排序**: 快速排序由C.A.R. Hoare在1960年提出,是一种高效的分治算法。其基本思想是选取一个基准值,将数组分为小于和大于基准值两部分,然后分别对这两部分进行快速排序。Flash演示会显示如何选取基准,...
快速排序由C.A.R. Hoare提出,采用“分而治之”的策略。选取一个“基准”元素,将数组分为两部分:小于基准的元素和大于基准的元素,然后对这两部分递归进行快速排序。快速排序平均时间复杂度为O(n log n),是目前...
本资源“java数据结构和算法图形演示操作--使用javaapplet进行演示”为学习者提供了一种直观理解这些概念的方式。 首先,我们要理解数据结构。数据结构是组织、存储和处理数据的特定方式,它优化了数据的存取效率。...
快速排序的平均时间复杂度为O(n log n),在最坏情况下为O(n^2)。 5. **选择排序(Selection Sort)**:选择排序每次从未排序的元素中找出最小(或最大)的一个元素,存放到排序序列的起始位置。共需进行n(n-1)/2次...
快速排序平均时间复杂度为O(n log n),但在最坏情况下是O(n^2)。 5. **归并排序**:也是基于分治策略,将数组分为两半,分别排序,然后再合并两个有序的部分。无论最好还是最坏情况,其时间复杂度都是O(n log n)。 ...
使用MFC单文档实现数据结构8种排序算法的图形界面动态演示,更加形象的展示排序过程,八种排序算法包括插入排序(直接插入排序、折半插入排序、希尔排序)、选择排序(直接选择排序、堆排序)、交换排序(冒泡排序、...