【排序算法】04快速排序
接上文:【排序算法】03堆排序
向工具类ArraySorterUtils中添加快速排序的实现,代码如下:
1 package org.liws1.sort; 2 3 import java.util.Arrays; 4 import java.util.Comparator; 5 6 /** 7 * 数组的排序,这里统一做升序排序 8 */ 9 public class ArraySorterUtils { 10 11 public static class QuickSorter implements IArraySorter { 12 13 @Override public <T extends Comparable<T>> void sort(T[] list) { 14 quickLoop(list, 0, list.length - 1); 15 } 16 17 18 @Override public <T> void sort(T[] list, Comparator<T> comp) { 19 // 省略实现,跟sort(T[] list),没差 20 } 21 22 /** 23 * 使srcDatas的[low~high]部分有序 24 * @param srcDatas 25 * @param low 26 * @param high 27 */ 28 private static <T extends Comparable<T>> void quickLoop(T[] srcDatas, int low, int high) { 29 if (low < high) { 30 int mid = getMiddle(srcDatas, low, high); 31 quickLoop(srcDatas, low, mid - 1); 32 quickLoop(srcDatas, mid + 1, high); 33 } 34 } 35 36 /** 37 * 快速排序基本操作: 38 * 找到一个中轴索引mid, 将datas分为三部分。 39 * 内部做了一些处理以使得[low ~ mid-1] < [mid] < [mid+1 ~ high] 40 * @param datas 待排数组 41 * @param low 低端索引 42 * @param high 高端索引 43 * @return 44 */ 45 private static <T extends Comparable<T>> int getMiddle(T[] datas, int low, int high) { 46 T midData = datas[low]; // 以第一个记录作为中轴记录 47 // 交替进行向左移动高端索引,向右移动低端索引,直到两索引相等 48 while (low < high) { 49 // 向左移动高端索引,直到碰到比中轴小的记录,将其移动到低端 50 while (low < high && datas[high].compareTo(midData) >= 0) { 51 high--; 52 } 53 datas[low] = datas[high]; 54 // 向右移动低端索引,知道碰到比中轴大的记录,将其移动到高端 55 while (low < high && datas[low].compareTo(midData) <= 0) { 56 low++; 57 } 58 datas[high] = datas[low]; 59 } 60 // 此时low = high, 这个位置就是我们要找的中轴索引mid 61 datas[high] = midData; 62 return high; // 返回中轴位置 63 } 64 65 } 66 67 }
测试代码如下:
package org.liws1.sort; import java.util.Arrays; import org.junit.Test; public class _Test { private Integer[] datas = { 30, 1, 29, 2, 28, 3, 27, 4, 26, 5, 25, 6, 24, 7, 23, 8, 22, 9, 21, 10, 20, 19, 15, 18, 12, 17, 11, 16, 14, 13 }; @Test public void testQuick(){ new ArraySorterUtils.QuickSorter().sort(datas); System.out.println(Arrays.toString(datas)); } // out:[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30] }