zoukankan      html  css  js  c++  java
  • 【开发者笔记】归并排序过程呈现之java内置GUI表示

      在网上看到一个视频将各种排序用视频表示出来,配上音乐,挺好玩的样子,就算是不会编程的人看到也会觉得很舒服,碰巧我也正在写归并算法,于是就用java的GUI实现一个。

      归并排序的时间复杂度是T(n)=O(nlgn),据说是比较排序的时间复杂度下限,缺点是排序算法和合并算法并不在同一空间,使得空间复杂度会有所提升。插入排序避免了归并排序的这一缺点但是又有一新缺点:空间复杂度为O(n2)..插入排序通过二分法改进就不同了,他是前二者的合体,既不在原地排序时间复杂度还是O(n2)……哈哈,开个玩笑。真正的合二者之优点为一的是堆排序,不过目前还没看懂堆排序~看懂了再来记一个。

      话不多说代码如下:

      1 package com.wyb.dyi.test;
      2 
      3 import java.awt.Color;
      4 import java.awt.Graphics;
      5 import java.awt.Toolkit;
      6 import java.util.Random;
      7 
      8 import javax.swing.JFrame;
      9 import javax.swing.JPanel;
     10 
     11 public class ShowMergeSort {
     12     static int[] array = getArray(Tool.W);/* 获得长度为屏幕宽度的乱序数组 */
     13     static updateShowArrayImg m = new updateShowArrayImg(array);/* 先显示当前乱序数组 */
     14 
     15     /**
     16      * 归并排序,并将排序过程打印成图像
     17      * @param args
     18      */
     19     public static void main(String[] args) {
     20         MyJPanel show = m.show;
     21         /* 开局暂停两秒 */
     22         try {
     23             Thread.currentThread();
     24             Thread.sleep(2000);
     25         } catch (Exception e) {
     26         }
     27 
     28         /* 开始归并排序 */
     29         m.updateShowArray(array);
     30         devide(array, 0, array.length - 1);
     31         m.updateShowArray(array);
     32     }
     33 
     34     /* 构造一个长度为length的高度为length/2的数组 */
     35     public static int[] getArray(int length) {
     36         /* 生成空数组 */
     37         int[] re = new int[length];
     38         /* 给数组附上高为length/2的升序数值 */
     39         for (int i = 0; i < re.length; i++)
     40             re[i] = i / 2;
     41         /* 讲有序数组打乱 */
     42         for (int i = 0; i < 20 * re.length; i++) {
     43             int index1 = new Random().nextInt(length);
     44             int index2 = new Random().nextInt(length);
     45             int temp = re[index1];
     46             re[index1] = re[index2];
     47             re[index2] = temp;
     48         }
     49 
     50         return re;
     51     }
     52 
     53     /* 分解数据 */
     54     public static void devide(int[] array, int left, int right) {
     55 
     56         if (left < right) {
     57             /* 寻找到中间下标 */
     58             int mid = (right + left) / 2;
     59             /* 从中间下标隔断,将前后两段分别分解 */
     60             devide(array, left, mid);
     61             /* 继续分割第二段 */
     62             devide(array, mid + 1, right);
     63             /* 分割完了,调用归并 */
     64             merge(array, left, mid, mid + 1, right);
     65         }
     66     }
     67 
     68     /* 归并,包含排序 */
     69     public static void merge(int[] array, int leftStart, int leftEnd,
     70             int rightStart, int rightEnd) {
     71         /* 新建临时数组,存放该次归并后的数据 */
     72         int[] temp = new int[array.length];
     73         /* 记录归并的左组和右组开始结束下标 */
     74         int ls = leftStart, le = leftEnd, rs = rightStart, re = rightEnd;
     75         /* 记录临时数组的存放位置 */
     76         int index = ls;
     77         /* 第一次比较归并,左组合右组中较小的入temp */
     78         while (ls <= le && rs <= re) {
     79             if (array[ls] <= array[rs]) {
     80                 temp[index] = array[ls];
     81                 index++;
     82                 ls++;
     83             } else {
     84                 temp[index] = array[rs];
     85                 index++;
     86                 rs++;
     87             }
     88         }
     89         /* 第二次选择归并,将array中剩余的未加入temp的数加入到temp中 */
     90         while (ls <= le) {
     91             temp[index] = array[ls];
     92             ls++;
     93             index++;
     94         }
     95         while (rs <= re) {
     96             temp[index] = array[rs];
     97             rs++;
     98             index++;
     99         }
    100         /* temp是经过调整后的array,此时一次归并完毕,返回数据进行下一次归并 */
    101         while (leftStart <= rightEnd) {
    102             array[leftStart] = temp[leftStart];
    103             leftStart += 1;
    104         }
    105         /* 打印本次归并结果,输出成图像 */
    106         m.updateShowArray(array);
    107     }
    108 
    109     /* 打印数组 */
    110     public static void printArray(int[] array) {
    111         for (int i = 0; i < array.length; i++)
    112             System.out.print(array[i] + "  ");
    113         System.out.println();
    114     }
    115 
    116 }
    117 
    118 /* 工具类,获取当前屏幕大小,用户初始化显示组件和new乱序数组 */
    119 class Tool {
    120     public static int W = (int) Toolkit.getDefaultToolkit().getScreenSize()
    121             .getWidth();/* 当前屏幕宽度 */
    122     public static int H = (int) Toolkit.getDefaultToolkit().getScreenSize()
    123             .getHeight();/* 当前屏幕高度 */
    124 }
    125 
    126 /* 画图面板 */
    127 class MyJPanel extends JPanel {
    128     private static final long serialVersionUID = 1L;
    129     int[] array;/* 用于接收构造方法传过来的数组,用于绘图 */
    130 
    131     public MyJPanel(int[] a) {
    132         array = a;
    133     }
    134 
    135     /* 绘图函数 */
    136     public void paintComponent(Graphics g) {
    137         /* 画笔置白色 */
    138         g.setColor(Color.WHITE);
    139         /* 擦除上一次绘制的团 */
    140         g.fillRect(0, 0, Tool.W, Tool.H);
    141         /* 画笔置黑色 */
    142         g.setColor(Color.black);
    143         /* 开始绘制当前数组图像,以(0,Tool.H)为原点,向右为x轴表数组下标,向上为y轴表当前下标所对应数组存置大小 */
    144         for (int i = 0; i < array.length; i++) {
    145             g.drawLine(i, Tool.H - 80, i, Tool.H - array[i] - 80);
    146         }
    147 
    148     }
    149 }
    150 
    151 /* 显示主框架JFrame类 */
    152 class updateShowArrayImg extends JFrame {
    153     private static final long serialVersionUID = 1L;
    154     MyJPanel show;
    155 
    156     /* 构造函数,初始化显示框架 */
    157     public updateShowArrayImg(int[] a) {
    158         show = new MyJPanel(a);
    159         show.setBounds(0, 0, Tool.W, Tool.H);
    160         this.setSize(Tool.W, Tool.H);
    161         this.setTitle("归并排序");
    162         this.setLocation(0, 0);
    163         this.add(show);
    164         this.setVisible(true);
    165         this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    166     }
    167 
    168     /**
    169      * 更新画布
    170      * 
    171      * @param a
    172      */
    173     public void updateShowArray(int[] a) {
    174         this.remove(show);
    175         show = new MyJPanel(a);
    176         this.add(show);
    177         this.setVisible(true);
    178     }
    179 }
    ShowMergeSort.java

      效果图奉上:

      优酷视频之GUI显示归并算法过程

    黑夜给了我黑色的眼睛,我却用它寻找光明
  • 相关阅读:
    [fw]error: aggregate value used where an integer was expected
    [fw]awk求和
    [fw]谈EXPORT_SYMBOL使用
    [fw]用Kprobes调试(debug)内核
    [FW]使用kprobes查看内核内部信息
    linux缺頁異常處理--內核空間[v3.10]
    用C语言给指定的内存地址赋值(通过指针)
    [fw]Linux 的 time 指令
    how to prevent lowmemorykiller from killing processes
    Android成长日记-Noification实现状态栏通知
  • 原文地址:https://www.cnblogs.com/wyongbo/p/showMergeSort.html
Copyright © 2011-2022 走看看