经典排序算法
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算法-------------\n", sort.sortName()); 238 Comparable[] data = (Comparable[])args[0]; 239 System.out.printf("排序前数据:%s\n", 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\n", Arrays.toString(data)); 244 System.out.printf("排序总耗时:%s毫秒\n", 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 }
运行结果