zoukankan      html  css  js  c++  java
  • 经典排序算法

    data.txt

    1 8,10,211,4,128,12,5,365,9,192,7,1,3,2,6,1024,11,13,20,54

    SortAlgorithm.java

      1 package io.guangsoft;
      2 
      3 import java.io.FileInputStream;
      4 import java.lang.reflect.InvocationHandler;
      5 import java.lang.reflect.Method;
      6 import java.lang.reflect.Proxy;
      7 import java.nio.ByteBuffer;
      8 import java.nio.channels.FileChannel;
      9 import java.util.Arrays;
     10 
     11 public class SortAlgorithm {
     12 
     13     //排序算法接口
     14     interface Sort {
     15         //排序算法名称
     16         String sortName();
     17         //元素大小的判断
     18         static boolean greater(Comparable x, Comparable y) {
     19             return x.compareTo(y) > 0;
     20         }
     21         //交换元素
     22         static void swap(Comparable[] data, int i, int j) {
     23             Comparable temp = data[i];
     24             data[i] = data[j];
     25             data[j] = temp;
     26         }
     27         //排序方法
     28         Comparable[] sort(Comparable[] data);
     29     }
     30 
     31     //冒泡排序
     32     static class BubbleSort implements Sort {
     33         @Override
     34         public String sortName() {
     35             return "冒泡排序";
     36         }
     37         @Override
     38         public Comparable[] sort(Comparable[] data) {
     39             //需要从由大到小范围进行n-1次筛选
     40             for(int i = 0; i < data.length - 1; i++) {
     41                 //在每次筛选的范围内逐个比较,将最小值冒泡到范围最左端
     42                 for(int j = data.length - 1; j > i; j--) {
     43                     if(Sort.greater(data[j - 1], data[j])) {
     44                         Sort.swap(data, j - 1, j);
     45                     }
     46                 }
     47             }
     48             return data;
     49         }
     50     }
     51 
     52     //选择排序
     53     static class SelectionSort implements Sort {
     54         @Override
     55         public String sortName() {
     56             return "选择排序";
     57         }
     58         @Override
     59         public Comparable[] sort(Comparable[] data) {
     60             //需要从由大到小范围进行n-1次筛选
     61             for(int i = 0; i < data.length - 1; i++) {
     62                 //在每次筛选的范围内选出最小值,将最小值交换到范围最左端
     63                 int minIndex = i;
     64                 for(int j = i + 1; j < data.length; j++) {
     65                     if(Sort.greater(data[minIndex], data[j])) {
     66                         minIndex = j;
     67                     }
     68                 }
     69                 Sort.swap(data, i, minIndex);
     70             }
     71             return data;
     72         }
     73     }
     74 
     75     //插入排序
     76     static class InsertionSort implements Sort {
     77         @Override
     78         public String sortName() {
     79             return "插入排序";
     80         }
     81         @Override
     82         public Comparable[] sort(Comparable[] data) {
     83             //需要从由小到大范围进行n-1次筛选
     84             for(int i = 1; i < data.length; i++) {
     85                 //在每次筛选的范围内将新增元素插入到有序位置
     86                 for(int j = i; j > 0; j--) {
     87                     if(Sort.greater(data[j - 1], data[j])) {
     88                         Sort.swap(data, j - 1, j);
     89                     } else {
     90                         break;
     91                     }
     92                 }
     93             }
     94             return data;
     95         }
     96     }
     97 
     98     //希尔排序
     99     static class ShellSort implements Sort {
    100         @Override
    101         public String sortName() {
    102             return "希尔排序";
    103         }
    104         @Override
    105         public Comparable[] sort(Comparable[] data) {
    106             int gap = 1;
    107             //确定初始增量
    108             while(gap < data.length / 2) {
    109                 gap = 2 * gap + 1;
    110             }
    111             //逐步二分缩小排序增量
    112             while(gap >= 1) {
    113                 //从中间位置开始向后逐步分组
    114                 for(int i = gap; i < data.length; i++) {
    115                     //组内进行插入排序
    116                     for(int j = i; j >= gap; j -= gap) {
    117                         if(Sort.greater(data[j - gap], data[j])) {
    118                             Sort.swap(data, j - gap, j);
    119                         } else {
    120                             break;
    121                         }
    122                     }
    123                 }
    124                 //缩小gap
    125                 gap >>>= 1;
    126             }
    127             return data;
    128         }
    129     }
    130 
    131     //归并排序
    132     static class MergeSort implements Sort {
    133         private static Comparable[] assist;
    134         @Override
    135         public String sortName() {
    136             return "归并排序";
    137         }
    138         @Override
    139         public Comparable[] sort(Comparable[] data) {
    140             assist = new Comparable[data.length];
    141             int lo = 0;
    142             int hi = data.length - 1;
    143             sort(data, lo, hi);
    144             return data;
    145         }
    146         //递归体
    147         private static void sort(Comparable[] data, int lo, int hi) {
    148             if(hi <= lo) return;
    149             int mid = lo + (hi - lo) / 2;
    150             sort(data, lo, mid);
    151             sort(data, mid + 1, hi);
    152             merge(data, lo, mid, hi);
    153         }
    154         //合并
    155         private static void merge(Comparable[] data, int lo, int mid, int hi) {
    156             //定义三个指针
    157             int i = lo, p1 = lo, p2 = mid + 1;
    158             //遍历,移动p1指针和p2指针,比较对应索引处的值,找出小的那个,放到辅助数组的对应索引处
    159             while(p1 <= mid && p2 <= hi) {
    160                 if(!Sort.greater(data[p1], data[p2])) {
    161                     assist[i++] = data[p1++];
    162                 } else {
    163                     assist[i++] = data[p2++];
    164                 }
    165             }
    166             //遍历,如果p1指针没有走完,那么顺序移动p1指针,把对应的元素放到辅助数组的对应索引处
    167             while(p1 <= mid) {
    168                 assist[i++] = data[p1++];
    169             }
    170             //遍历,如果p2指针没有走完,那么顺序移动p1指针,把对应的元素放到辅助数组的对应索引处
    171             while(p2 <= hi) {
    172                 assist[i++] = data[p2++];
    173             }
    174             //把辅助数组中的元素拷贝到原数组中
    175             for(int index = lo; index <= hi; index++) {
    176                 data[index] = assist[index];
    177             }
    178         }
    179     }
    180 
    181     //快速排序
    182     static class QuickSort implements Sort {
    183         @Override
    184         public String sortName() {
    185             return "快速排序";
    186         }
    187         @Override
    188         public Comparable[] sort(Comparable[] data) {
    189             int lo = 0, hi = data.length - 1;
    190             sort(data, lo, hi);
    191             return data;
    192         }
    193         //递归体
    194         private static void sort(Comparable[] data, int lo, int hi) {
    195             if(hi <= lo) return;
    196             int partition = partition(data, lo, hi);
    197             sort(data, lo, partition - 1);
    198             sort(data, partition + 1, hi);
    199         }
    200         //分组
    201         private static int partition(Comparable[] data, int lo, int hi) {
    202             //确定分界值
    203             Comparable key = data[lo];
    204             //定义两个指针,分别指向待切分元素的最小索引处和最大索引处的下一个位置
    205             int left = lo, right = hi + 1;
    206             //切分
    207             while(true) {
    208                 //先从左往右扫描,移动right指针,找到一个比分界值小的元素,停止
    209                 while(!Sort.greater(key, data[--right])) {
    210                     if(right == lo) break;
    211                 }
    212                 //再从左往右扫描,移动left指针,找到一个比分界值大的元素,停止
    213                 while(!Sort.greater(data[++left], key)) {
    214                     if(left == hi) break;
    215                 }
    216                 //判断left>=right,如果是,则证明元素扫描完毕,结束循环,如果不是,则交换元素即可
    217                 if(left >= right) {
    218                     break;
    219                 } else {
    220                     Sort.swap(data, left, right);
    221                 }
    222             }
    223             //交换分界值
    224             Sort.swap(data, lo, right);
    225             return right;
    226         }
    227     }
    228 
    229     //动态代理执行测试
    230     static class DynamicSort {
    231         //动态代理处理器
    232         static class SortInvocationHandler implements InvocationHandler {
    233             private Sort sort;
    234             SortInvocationHandler(Sort sort) { this.sort = sort;}
    235             @Override
    236             public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    237                 System.out.printf("-------------测试%s算法-------------
    ", sort.sortName());
    238                 Comparable[] data = (Comparable[])args[0];
    239                 System.out.printf("排序前数据:%s
    ", Arrays.toString(data));
    240                 long start = System.currentTimeMillis();
    241                 data = (Comparable[]) method.invoke(sort, args);
    242                 long end = System.currentTimeMillis();
    243                 System.out.printf("排序后数据:%s
    ", Arrays.toString(data));
    244                 System.out.printf("排序总耗时:%s毫秒
    ", end - start);
    245                 return null;
    246             }
    247         }
    248         //执行代理
    249         public static void sort(Comparable[] data, Class clazz) throws Throwable {
    250             Sort sort = (Sort) clazz.getDeclaredConstructor().newInstance();
    251             sort = (Sort)Proxy.newProxyInstance(clazz.getClassLoader(), clazz.getInterfaces(), new SortInvocationHandler(sort));
    252             sort.sort(data);
    253         }
    254     }
    255 
    256     //NIO加载数据
    257     public static<T> T[] loadData(Class<T> c) throws Throwable{
    258         FileInputStream fileInputStream = new FileInputStream(Sort.class.getClassLoader().getResource("data.txt").getPath());
    259         FileChannel fileChannel = fileInputStream.getChannel();
    260         ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
    261         StringBuffer stringBuffer = new StringBuffer();
    262         int length = -1;
    263         while((length = fileChannel.read(byteBuffer)) != -1) {
    264             byteBuffer.clear();
    265             byte[] bytes = Arrays.copyOf(byteBuffer.array(), length);
    266             stringBuffer.append(new String(bytes));
    267         }
    268         fileChannel.close();
    269         fileInputStream.close();
    270         return (T[]) Arrays.stream(stringBuffer.toString().split(",")).mapToInt(Integer::valueOf).boxed().toArray(Integer[]::new);
    271     }
    272 
    273     //启动类
    274     public static void main(String args[]) throws Throwable {
    275         Comparable[] data = loadData(Integer.class);
    276         //测试冒泡排序
    277         DynamicSort.sort(Arrays.copyOf(data, data.length), BubbleSort.class);
    278         //测试选择排序
    279         DynamicSort.sort(Arrays.copyOf(data, data.length), SelectionSort.class);
    280         //测试插入排序
    281         DynamicSort.sort(Arrays.copyOf(data, data.length), InsertionSort.class);
    282         //测试希尔排序
    283         DynamicSort.sort(Arrays.copyOf(data, data.length), ShellSort.class);
    284         //测试归并排序
    285         DynamicSort.sort(Arrays.copyOf(data, data.length), MergeSort.class);
    286         //测试快速排序
    287         DynamicSort.sort(Arrays.copyOf(data, data.length), QuickSort.class);
    288     }
    289 
    290 }

    运行结果

  • 相关阅读:
    C# 添加修改防火墙端口及程序
    Winform 多线程--解决界面卡死问题
    ScreenOper
    KVM的VPS主机在Centos6.x下修改系统时间
    Java IO和File类
    Java动态代理Proxy类源码分析
    Java IO之字节流
    Java IO之字符流
    两台计算机之间如何通讯
    Java引用类型原理
  • 原文地址:https://www.cnblogs.com/guanghe/p/13626678.html
Copyright © 2011-2022 走看看