Java 版快速排序 + 最挫的优化
最近复习算法发现快排忘得差不多了,其他排序方法还好。
两年之前在大一时写过一篇 六种常见的排序方法,当时是用C++写的,那时的代码可读性也比较差,今天重新写一下。
快速排序其实有不同的写法,不过其基本思想+最挫的优化如下: 先在数组中选择一个数字(随机选择可在一定程度避免快排复杂度退化),接下来把数字分为两部分,比选中的数字小的移动到数组的左边,比选中的数大的放在数组的右边(为了方便先把选中的数放在数组最后,交换完后在插入到中间)。接下来可以用递归的思想,对每次选中的数左右两边进行排序。
Java实现代码如下:
1 public class QuickSorter { 2 3 public void sort(Comparable[] arr) { 4 sortCore(arr, 0, arr.length - 1); 5 } 6 7 private void sortCore(Comparable[] arr, int st, int ed) { 8 if(st == ed) 9 return; 10 int id = partition(arr, st, ed); 11 if(id > st) 12 sortCore(arr, st, id - 1); 13 if(id < ed) 14 sortCore(arr, id + 1, ed); 15 } 16 17 private int partition(Comparable[] arr, int st, int ed) { 18 int id = randomSelect(st, ed); 19 swap(arr, id, ed); 20 int small = st - 1; 21 for(int i = st; i < ed; ++i) 22 if(arr[i].compareTo(arr[ed]) < 0) 23 swap(arr, ++small, i); 24 swap(arr, ++small, ed); 25 return small; 26 } 27 28 // 生成[st, ed]内随机数 29 private int randomSelect(int st, int ed) { 30 double r = Math.random(); 31 double t = st + (ed - st + 1) * r; 32 return (int) Math.floor(t); 33 } 34 35 // 交换数组arr中下标为a和b的对象 36 private void swap(Object[] arr, int a, int b) { 37 Object t = arr[a]; 38 arr[a] = arr[b]; 39 arr[b] = t; 40 } 41 }
下面提供一个测试类:
1 import org.junit.Test; 2 3 import java.util.Arrays; 4 import java.util.Random; 5 6 import static org.junit.Assert.*; 7 8 /** 9 * Created by kun36 on 2017/2/2. 10 */ 11 public class QuickSorterTest { 12 13 private QuickSorter sorter = new QuickSorter(); 14 15 @Test 16 public void sort1() throws Exception { 17 Integer[] arr = {1, 2, 3}; 18 sorter.sort(arr); 19 assertArrayEquals(new Integer[]{1, 2, 3}, arr); 20 } 21 22 @Test 23 public void sort2() throws Exception { 24 Integer[] arr = {3, 2, 1}; 25 sorter.sort(arr); 26 assertArrayEquals(new Integer[]{1, 2, 3}, arr); 27 } 28 29 @Test 30 public void sort3() throws Exception { 31 Integer[] arr = {2, 3, 1}; 32 sorter.sort(arr); 33 assertArrayEquals(new Integer[]{1, 2, 3}, arr); 34 } 35 36 @Test 37 public void sort4() throws Exception { 38 final int len = 100; 39 Random random = new Random(); 40 Integer[] arr1 = new Integer[len]; 41 Integer[] arr2 = new Integer[len]; 42 for(int i = 0; i < len; ++i) 43 arr1[i] = arr2[i] = random.nextInt(); 44 sorter.sort(arr1); 45 Arrays.sort(arr2); 46 assertArrayEquals(arr1, arr2); 47 } 48 }