鱼C论坛

 找回密码
 立即注册
查看: 2105|回复: 2

[技术交流] 动手写冒泡排序图形演示程序,你也可以

[复制链接]
发表于 2016-2-27 17:01:02 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
各位朋友你们好,今天教大家写冒泡排序演示程序,使用语言为Java,不会Java也没关系,其他语言一样可以举一反三。

写演示程序有什么好处,第一是加深对编程语言的理解与应用;第二就是加深对数据结构和算法的理解,防遗忘;第三就是通过这个演示程序出一套视频,教大家。

先看程序运行最终截图:
BubbleSort.png

新建按钮可以新建要排序的元素;单步按钮可以观察排序全过程;运行按钮相当于自动点击单步按钮。

代码如下,已经有很多注释,不解释。

Bar.java

  1. package com.algorithm.sort;

  2. import java.awt.Color;

  3. public class Bar {
  4.         //方块的宽、方块与方块的距离、方块的最大宽度
  5.         public static final int WIDTH = 20, INTERVAL = 10, MAX_HEIGHT = 200;
  6.         //方块的高
  7.         private int height;
  8.         //方块的颜色
  9.         private Color color;

  10.         public Bar(int height, Color color) {
  11.                 this.height = height;
  12.                 this.color = color;
  13.         }

  14.         public int getHeight() {
  15.                 return height;
  16.         }

  17.         public void setHeight(int height) {
  18.                 this.height = height;
  19.         }

  20.         public Color getColor() {
  21.                 return color;
  22.         }

  23.         public void setColor(Color color) {
  24.                 this.color = color;
  25.         }
  26. }
复制代码


BarGroup.java

  1. package com.algorithm.sort;

  2. import java.awt.*;

  3. public abstract class BarGroup {
  4.         //进行相应排序界面绘制,需要子类重写
  5.         public abstract void draw(Graphics g);
  6.         //单步进行相应排序,需要子类重写
  7.         public abstract void sortStep();
  8.         //判断是否完成排序
  9.         public abstract boolean isDone();
  10.        
  11.         /**
  12.          * 初始化方块
  13.          * @param size 创建方块的大小
  14.          * @param isRandom 如果为ture,表示随机生成方块;否则逆序生成方块
  15.          * @return 生成的方块
  16.          */
  17.         public Bar[] initBarArray(int size, boolean isRandom) {
  18.                 Bar[] barArray = new Bar[size];
  19.                 if (isRandom) {
  20.                         for (int i = 0; i < size; i++) {
  21.                                 int height = (int) (Math.random() * Bar.MAX_HEIGHT);
  22.                                 int r = (int) (Math.random() * 255);
  23.                                 int g = (int) (Math.random() * 255);
  24.                                 int b = (int) (Math.random() * 255);
  25.                                 barArray[i] = new Bar(height, new Color(r, g, b));
  26.                         }
  27.                 } else {
  28.                         for (int i = 0; i < size; i++) {
  29.                                 int height = Bar.MAX_HEIGHT - (Bar.MAX_HEIGHT * i) / size;
  30.                                 int r = (int) (Math.random() * 255);
  31.                                 int g = (int) (Math.random() * 255);
  32.                                 int b = (int) (Math.random() * 255);
  33.                                 barArray[i] = new Bar(height, new Color(r, g, b));
  34.                         }
  35.                 }
  36.                 return barArray;
  37.         }
  38.        
  39.         /**
  40.          * 绘制一个方块
  41.          * @param g 画笔
  42.          * @param barArray 方块数组(根当于要排序的元素)
  43.          * @param index 欲绘制方块的索引号
  44.          */
  45.         public void drawOneBar(Graphics g, Bar[] barArray, int index) {
  46.                 int height = barArray[index].getHeight();
  47.                 Color color = barArray[index].getColor();
  48.                 int x = 35 + index * (Bar.WIDTH + Bar.INTERVAL);
  49.                 int y = 250 - height;
  50.                
  51.                 g.setColor(color);
  52.                 g.fill3DRect(x, y, Bar.WIDTH, height, true);
  53.         }
  54.        
  55.         /**
  56.          * 绘制一个箭头
  57.          * @param g 画笔
  58.          * @param color 箭头的颜色
  59.          * @param str 箭头下面的文本
  60.          * @param index 箭头上方对应的方块索引
  61.          * @param arrowLength 箭头的长度
  62.          */
  63.         public void arrowText(Graphics g, Color color, String str, int index, int arrowLength) {
  64.                 int x = 35 + index * (Bar.WIDTH + Bar.INTERVAL);
  65.                 int y = 250 + 15 * arrowLength;
  66.                 g.setColor(color);
  67.                 g.drawString(str, x, y);
  68.                 g.drawLine(x + Bar.WIDTH / 2, 252, x + Bar.WIDTH / 2, y - 15);
  69.                 g.drawLine(x + Bar.WIDTH / 2, 252, x + Bar.WIDTH / 2 - 3, 257);
  70.                 g.drawLine(x + Bar.WIDTH / 2, 252, x + Bar.WIDTH / 2 + 3, 257);
  71.         }
  72.        
  73.         /**
  74.          * 交换两个方块的位置
  75.          * @param barArray 方块数组
  76.          * @param i 第一个要交换的方块
  77.          * @param j 第二个要交换的方块
  78.          */
  79.         public void swap(Bar[] barArray, int i, int j) {
  80.                 Bar tmp = barArray[i];
  81.                 barArray[i] = barArray[j];
  82.                 barArray[j] = tmp;
  83.         }
  84. }
复制代码


BubbleSort.java

  1. package com.algorithm.sort;

  2. import java.awt.*;

  3. /**
  4. * 冒泡排序类
  5. * @author Focus100
  6. *
  7. */
  8. public class BubbleSort extends BarGroup {
  9.         //方块数组的大小
  10.         private static final int ARRAY_SIZE = 10;
  11.         //方块数组
  12.         private Bar barArray[];
  13.         //方块的inner、outer指针
  14.         private int inner, outer;
  15.         //比较次数、交换次数
  16.         private int comps, swaps;
  17.         //是否完成排序
  18.         private boolean isDone;
  19.        
  20.         public BubbleSort(boolean isRandom) {
  21.                 //初始化方块数组,大小为10个
  22.                 barArray = initBarArray(ARRAY_SIZE, isRandom);
  23.                 //inner一开始指向第一个元素
  24.                 inner = comps = swaps = 0;
  25.                 //outer一开始指向最后一个元素
  26.                 outer = ARRAY_SIZE - 1;
  27.                 isDone = false;
  28.         }
  29.        
  30.         /**
  31.          * 完成冒泡排序界面的绘制
  32.          */
  33.         public void draw(Graphics g) {
  34.                 for (int i = 0; i < barArray.length; i++)
  35.                         drawOneBar(g, barArray, i);
  36.         g.setColor(Color.BLACK);
  37.         g.drawString("比较次数 = " + comps, 10, 30);
  38.         g.drawString("交换次数 = " + swaps, 10, 15);
  39.         
  40.         arrowText(g, Color.BLUE, "inner", inner, 3);
  41.         arrowText(g, Color.BLUE, "inner+1", inner + 1, 3);
  42.         arrowText(g, Color.RED, "outer", outer, 4);
  43.         if (isDone) {
  44.                 g.drawString("状态:排序完毕", 10, 45);
  45.                 return;
  46.         }
  47.         if (barArray[inner].getHeight() > barArray[inner + 1].getHeight())
  48.                 g.drawString("状态:需交换", 10, 45);
  49.         else
  50.                 g.drawString("状态:不需交换", 10, 45);
  51.         }
  52.        
  53.         /**
  54.          * 单步进行冒泡排序
  55.          */
  56.         public void sortStep() {
  57.                 if (isDone)
  58.                         return;
  59.                 //比较次数加1
  60.                 comps++;
  61.                 //如果前面的元素大于后面的元素,则交换
  62.                 if (barArray[inner].getHeight() > barArray[inner + 1].getHeight()) {
  63.                         swap(barArray, inner, inner + 1);
  64.                         swaps++;  //交换次数加1
  65.                 }
  66.                 inner++;
  67.                 //inner最多到达outer-1的位置,outer后面的元素是排好的元素
  68.                 if (inner > outer - 1) {
  69.                         inner = 0;
  70.                         outer--;
  71.                         //outer最多>=1,如果等于0表示排序完成
  72.                         if (outer == 0)
  73.                                 isDone = true;
  74.                 }
  75.         }
  76.        
  77.         /**
  78.          * 判断是否完成排序
  79.          */
  80.         public boolean isDone() {
  81.                 return isDone;
  82.         }
  83. }
复制代码


SortPanel.java

  1. package com.algorithm.sort;

  2. import java.awt.*;
  3. import java.awt.event.*;

  4. import javax.swing.*;

  5. public class SortPanel extends JPanel implements ActionListener, Runnable {
  6.         private JButton btnNew, btnStep, btnRun;
  7.         private BarGroup barSort;  //排序方块类
  8.         private final int WIDTH = 370, HEIGHT = 320;
  9.         private boolean isRun = false, isRandom = true;  //是否用线程排序、是否随机排序

  10.         public SortPanel() {
  11.                 //设置宽和高
  12.                 setPreferredSize(new Dimension(WIDTH, HEIGHT));
  13.                 //设置为流式布局,右对齐
  14.                 setLayout(new FlowLayout(FlowLayout.RIGHT));
  15.                 //添加三个按钮,并添加监听
  16.                 btnNew = new JButton("新建");
  17.                 btnNew.addActionListener(this);
  18.                 add(btnNew);
  19.                 btnStep = new JButton("单步");
  20.                 btnStep.addActionListener(this);
  21.                 add(btnStep);
  22.                 btnRun = new JButton("运行");
  23.                 btnRun.addActionListener(this);
  24.                 add(btnRun);
  25.                 //创建方块类
  26.                 barSort = new BubbleSort(isRandom);
  27.                 //启动线程
  28.                 new Thread(this).start();
  29.         }

  30.         @Override
  31.         public void paint(Graphics g) {
  32.                 super.paint(g);
  33.                 //绘制排序界面
  34.                 barSort.draw(g);
  35.         }

  36.         @Override
  37.         public void actionPerformed(ActionEvent e) {
  38.                 switch (e.getActionCommand()) {
  39.                 case "新建":
  40.                         //点一次随机排序,再点一次逆序排序
  41.                         isRandom = isRandom ? false : true;
  42.                         barSort = new BubbleSort(isRandom);
  43.                         isRun = false;
  44.                         break;
  45.                 case "单步":
  46.                         barSort.sortStep();
  47.                         isRun = false;
  48.                         break;
  49.                 case "运行":
  50.                         isRun = true;
  51.                         break;
  52.                 }
  53.                 repaint();
  54.         }
  55.        
  56.         /**
  57.          * 用线程自动完成排序
  58.          */
  59.         @Override
  60.         public void run() {
  61.                 while (true) {
  62.                         if (isRun && barSort.isDone()) {
  63.                                 isRun = false;
  64.                                 return;
  65.                         }
  66.                        
  67.                         if (isRun) {
  68.                                 barSort.sortStep();
  69.                                 repaint();
  70.                                 try {
  71.                                         Thread.sleep(350);
  72.                                 } catch (InterruptedException e) {
  73.                                         e.printStackTrace();
  74.                                 }
  75.                         }
  76.                 }
  77.         }
  78. }
复制代码


SoftFrame.java

  1. package com.algorithm.sort;

  2. import javax.swing.*;

  3. public class SoftFrame extends JFrame {
  4.        
  5.         public SoftFrame() {
  6.                 this.add(new SortPanel());
  7.                 this.setTitle("冒泡排序");  //设置窗口标题
  8.                 this.setLocation(50, 100);  //设置窗口显示位置
  9.                 this.pack(); //适应子窗口大小
  10.                 this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  //设置窗口关闭方式
  11.         }
  12.        
  13.         public static void main(String[] args) {
  14.                 SoftFrame frame = new SoftFrame();
  15.                 frame.setVisible(true);
  16.         }
  17. }
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2016-2-27 17:29:42 | 显示全部楼层
版主能对程序运行最终截图进行一下说明吗
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-2-27 18:19:26 | 显示全部楼层
西电图图 发表于 2016-2-27 17:29
版主能对程序运行最终截图进行一下说明吗

命令行代码:

  1. public void BubbleSort() {
  2.         int arr[] = {5, 4, 3, 2, 1};
  3.        
  4.         for (int outer = arr.length - 1; outer >= 1; outer--) {
  5.                 for (int inner = 0; inner < outer; inner++) {
  6.                         if (arr[inner] > arr[inner + 1]) {
  7.                                 int tmp = arr[inner];
  8.                                 arr[inner] = arr[inner + 1];
  9.                                 arr[inner + 1] = tmp;
  10.                         }
  11.                 }
  12.         }
  13.        
  14.         for (int i: arr) {
  15.                 System.out.println(i);
  16.         }
  17. }
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-28 15:44

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表