快速排序法2图形演示

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);
  }
 }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值