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显示归并算法过程

    黑夜给了我黑色的眼睛,我却用它寻找光明
  • 相关阅读:
    欧拉公式
    isap的一些想法
    错误合集
    Hello World
    PAT (Advanced Level) Practice 1068 Find More Coins
    PAT (Advanced Level) 1087 All Roads Lead to Rome
    PAT (Advanced Level) 1075 PAT Judge
    PAT (Advanced Level) 1067 Sort with Swap(0, i)
    PAT (Advanced Level) 1017 Queueing at Bank
    PAT (Advanced Level) 1025 PAT Ranking
  • 原文地址:https://www.cnblogs.com/wyongbo/p/showMergeSort.html
Copyright © 2011-2022 走看看